[转贴]C#事件机制初次接触

C#是微软出品的新一代编程语言是VS.NET工具集中的主打语言,C#的一个重要特性之一就是支持“事件(Event)”。在C#中为一个类添加事件支持是非常简单的:

打开VS.NET,新建一个C# Console Application,执行“项目”->“添加类”菜单功能,添加一个“MyClass”类:

using System;

 

namespace ConsoleApplication1

{

     //声明一个delegate

     public delegate void EventHandler();

 

     /// <summary>

     /// 测试C#event机制。

     /// </summary>

     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 被调用,valueHashCode为:" + value.GetHashCode());

 

                   if(value != null){m_Handler = value;};//设置m_Handler域保存新的handler

              }

              remove//删除访问器

              {

                   Console.WriteLine("AEvent remove 被调用,valueHashCode为:" + value.GetHashCode());

 

                   if(value == m_Handler){m_Handler = null;}//m_Handlernull,该事件将不再被激发

              }

         }

         public MyClass()

         {

              //

              // TODO: 在此处添加构造函数逻辑

              //

         }

 

     }

}

 

然后在主文件Class1.cs中输入如下代码:

using System;

 

namespace ConsoleApplication1

{

     /// <summary>

     /// Class1 的摘要说明。

     /// </summary>

     class Class1

     {

         /// <summary>

         /// 应用程序的主入口点。

         /// </summary>

         [STAThread]

         static void Main (string[] args)

         {

              //

              // TODO: 在此处添加代码以启动应用程序

              //

              //实例化一个MyClass的对象Obj

              MyClass Obj = new MyClass();

              //基于MyEventHandler()函数定义一个EventHandler

              EventHandler MyHandler = new EventHandler(MyEventHandler);

              Console.WriteLine("MyHandlerHashCode为:"+MyHandler.GetHashCode());

              Console.WriteLine();

 

              //预定事件

              Console.WriteLine("Obj.AEvent += Myhandler 被调用");

              Obj.AEvent += MyHandler;

              //激发事件

              Console.WriteLine("Main函数激发ObjAEvent事件!");

              Obj.FireAEvent();

              //撤消事件

              Console.WriteLine("Obj.AEvent -= Myhandler 被调用");

              Obj.AEvent -= MyHandler;

              Console.WriteLine();

 

              //再次试图激发事件

              Console.WriteLine("Main函数试图在撤消事件后激发ObjAEvent事件!");

              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++等语言中是必须自己写代码实现的。

你可能感兴趣的:([转贴]C#事件机制初次接触)