C#事件机制初次接触(事件访问器)

来源:互联网 发布:博士德汽配软件 编辑:程序博客网 时间:2024/05/16 04:31
 
C#事件机制初次接触
C#是微软出品的新一代编程语言是VS.NET工具集中的主打语言,C#的一个重要特性之一就是支持“事件(Event)”。在C#中为一个类添加事件支持是非常简单的:
打开VS.NET,新建一个C# Console Application,执行“项目”->“添加类”菜单功能,添加一个“MyClass”类:
using System;
 
namespace ConsoleApplication1
{
     //声明一个delegate
     public delegate void EventHandler();
 
     ///
     ///测试C#的event机制。
     ///
     public class MyClass
     {
         //声明一个成员变量来保存事件句柄(事件被激发时被调用的delegate)
         private EventHandler m_Handler = null;
         //激发事件
         public void FireAEvent()
         {
              if(m_Handler != null)
              {
                   m_Handler();
              }
         }
         //声明事件
         public event EventHandler AEvent
         {
              add//添加访问器
              {
                   //注意,访问器中实际包含了一个名为value的隐含参数
                   //该参数的值即为客户程序调用+=时传递过来的delegate
                   Console.WriteLine("AEvent add 被调用,value的HashCode为:" + value.GetHashCode());
 
                   if(value != null){m_Handler = value;};//设置m_Handler域保存新的handler
              }
              remove//删除访问器
              {
                   Console.WriteLine("AEvent remove 被调用,value的HashCode为:" + value.GetHashCode());
 
                   if(value == m_Handler){m_Handler = null;}//置m_Handler为null,该事件将不再被激发
              }
         }
         public MyClass()
         {
              //
              // TODO: 在此处添加构造函数逻辑
              //
         }
 
     }
}
 
然后在主文件Class1.cs中输入如下代码:
using System;
 
namespace ConsoleApplication1
{
     ///
     /// Class1 的摘要说明。
     ///
     class Class1
     {
         ///
         ///应用程序的主入口点。
         ///
         [STAThread]
         static void Main(string[] args)
         {
              //
              // TODO: 在此处添加代码以启动应用程序
              //
              //实例化一个MyClass的对象Obj
              MyClass Obj = new MyClass();
              //基于MyEventHandler()函数定义一个EventHandler
              EventHandler MyHandler = new EventHandler(MyEventHandler);
              Console.WriteLine("MyHandler的HashCode为:"+MyHandler.GetHashCode());
              Console.WriteLine();
 
              //预定事件
              Console.WriteLine("Obj.AEvent += Myhandler 被调用");
              Obj.AEvent += MyHandler;
              //激发事件
              Console.WriteLine("Main函数激发Obj的AEvent事件!");
              Obj.FireAEvent();
              //撤消事件
              Console.WriteLine("Obj.AEvent -= Myhandler 被调用");
              Obj.AEvent -= MyHandler;
              Console.WriteLine();
 
              //再次试图激发事件
              Console.WriteLine("Main函数试图在撤消事件后激发Obj的AEvent事件!");
              Obj.FireAEvent();
 
              Console.WriteLine("---程序运行完毕!---");
              Console.ReadLine();
         }
         //真正的事件处理函数
         static void MyEventHandler()
         {
              Console.WriteLine("This is a Event!");
         }
 
     }
}
运行,我们从程序的输出结果中可以看出,当我们在Main函数中调用
Obj.FireAEvent();
方法后,我们的MyEventHandler事件处理函数被调用,屏幕输出 “This is a Event!”。
 
下面我们结合该Console程序的输出结果分析一下这个MyEventHandler是如何被调用的:
――――――――――――――――――――――――――――
1MyHandlerHashCode为:10048139
 
2Obj.AEvent += Myhandler 被调用
3AEvent add 被调用,valueHashCode为:10048139
4Main函数激发ObjAEvent事件!
5This is a Event!
6Obj.AEvent -= Myhandler 被调用
7AEvent remove 被调用,valueHashCode为:10048139
 
8Main函数试图在撤消事件后激发ObjAEvent事件!
---程序运行完毕!---
――――――――――――――――――――――――――――
首先,Obj.AEvent += Myhandler被调用后,MyHandler被作为隐含的value参数传递给MyClass中的事件AEventadd访问器,我们在该访问器中设置m_Handler成员变量为传递过来的value(通过HashCode我们可以知道该参数和Main函数中的MyHandler为同一对象)即我们的MyHandler(该代理实际上指向我们的MyEventHandler函数),当Main函数调用Obj.FireEvent()时,Objm_Handler被调用,也就是我们的MyEventHandler被调用。
Obj.AEvent -= Myhandler被调用时,AEventremove访问器被调用,我们在这里置m_Handlernull,撤消该事件,Main函数再次FireEvent时,由于Objm_Handlernull,所以直接返回到Main函数中,事件处理函数不再被调用。
 
通过这个简单的例子,我们可以从整体上了解C#Event机制的一般用法和浅层原理(深层的原理我还没有弄明白^_^)。可以看到,在C#中事件机制是在语言级通过“函数代理(delegate)”和“event”关键字被直接支持的,而在C++等语言中是必须自己写代码实现的。
原文:http://www.farproc.com/Article/ShowArticle.asp?ArticleID=188
原创粉丝点击