http://tmsoft.lsxy.com/index.php?id=375&load=read
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是如何被调用的:
――――――――――――――――――――――――――――
(
1
)
MyHandler
的
HashCode
为:
10048139
(
2
)
Obj.AEvent += Myhandler
被调用
(
3
)
AEvent add
被调用,
value
的
HashCode
为:
10048139
(
4
)
Main
函数激发
Obj
的
AEvent
事件!
(
5
)
This is a Event!
(
6
)
Obj.AEvent -= Myhandler
被调用
(
7
)
AEvent remove
被调用,
value
的
HashCode
为:
10048139
(
8
)
Main
函数试图在撤消事件后激发
Obj
的
AEvent
事件!
---程序运行完毕!---
――――――――――――――――――――――――――――
首先,
Obj.AEvent += Myhandler
被调用后,
MyHandler
被作为隐含的
value
参数传递给
MyClass
中的事件
AEvent
的
add
访问器,我们在该访问器中设置
m_Handler
成员变量为传递过来的
value
(通过
HashCode
我们可以知道该参数和
Main
函数中的
MyHandler
为同一对象)即我们的
MyHandler
(该代理实际上指向我们的
MyEventHandler
函数),当
Main
函数调用
Obj.FireEvent()
时,
Obj
的
m_Handler
被调用,也就是我们的
MyEventHandler
被调用。
Obj.AEvent -= Myhandler
被调用时,
AEvent
的
remove
访问器被调用,我们在这里置
m_Handler
为
null
,撤消该事件,
Main
函数再次
FireEvent
时,由于
Obj
的
m_Handler
为
null
,所以直接返回到
Main
函数中,事件处理函数不再被调用。
通过这个简单的例子,我们可以从整体上了解
C#
的
Event
机制的一般用法和浅层原理(深层的原理我还没有弄明白
^_^
)。可以看到,在
C#
中事件机制是在语言级通过“函数代理(
delegate
)”和“
event
”关键字被直接支持的,而在
C++
等语言中是必须自己写代码实现的。