言简意赅的解释
先说总结:事件就是委托链(也就是继承自MulticastDelegate类的委托,用delegate声明的委托就是继承自MulticastDelegate类的)的属性,事件有一个Add方法、一个Remove方法以及一个私有委托链。也就是说,声明一个事件,类似于声明一个进行封装了的委托链。
很多人说:“总是感觉委托和事件没什么区别,调用事件不就是相当于调用多个委托么?”
不全对,事件之于委托,就相当于,集合的属性之于集合的元素,注意:事件封装了私有委托链,事件其实就是一个特殊的多播委托(也叫委托链)。
举个例子:
class Program
{
public delegate void SendHandler(string str); // 用delegate声明的委托就是继承自MulticastDelegate类的
public event SendHandler SendEvent; // 用刚声明的委托类型来声明事件
static void Main(string[] args)
{ }
}
编译后,用ILDASM.EXE打开那个.exe,就会发现SendHandler委托被编译为了一个叫做SendHandler的类,声明的委托就是一个类嘛。
SendEvent事件则是被编译成了包含一个add_前缀的方法(通过调用Delegate.Combine()方法来实现)和一个remove_前缀的方法(通过调用Delegate.Remove()方法来实现)。这是默认实现,事件是可以自行重写add和remove的。
好了,前面说的都不是废话,你还会看到一个私有字段SendEvent(蔚蓝色菱形),其存储了对事件处理方法的引用。而add_前缀方法和remove_前缀方法起到的就是类似C#属性访问器中get_和set_方法的封装私有字段的作用,使用事件能访问私有委托。简而言之,事件就是用来访问私有的委托字段,让应用程序的代码更加的安全。