分享

C#中的delegate和event

 kittywei 2012-02-17

最近看Effective C#,看到委托(delegate)和事件(event)这部分,没看懂,于是深入了解下,下面简单记录一些个人理解。

 

首先来看委托,功能上来说其实就是个函数指针(原谅我既有的C++思维),只不过它提供了类型安全,可以支持各种方法(包括对象的成员方法,会自动传递对象引用本身,这点函数指针其实很容易模拟,只不过这里强制化了),以及运行时的安全性(即不会因为没有指向而报错)。这看起来像是一个封装的更加好的安全版的函数指针。另外,委托还支持多播,即一个委托可以挂接多个函数,当使用委托发起调用时,可以依次调用每个函数。从概念上说,委托是一种特殊的机制,在关键词上和class/struct是一个层次,用于创建委托的类型。

声明一个委托类型的语法格式如下:

[修饰词 public/private...] delegate [返回值类型 void/int...] [委托类型名称] ( [参数列表] );

一个声明实例:

public delegate void MyDelegate(int s);(注意是声明,不是具体对象,可以放在class外)

创建一个委托类型的实例:

MyDelegate myDelegate = new MyDelegate(someConcreteFunc);

 

再来看事件,事件是一种特殊的委托类型的对象。它的特殊之处有二,一是它的签名是特殊的,二是针对它的操作也是有限制的。所谓签名就是指函数原型,即固定的返回值和参数的类型。操作的限制是只能使用+=和-=操作,而不能使用赋值操作(=)。

事件的语法格式如下:

[修饰词 public/private...] event [某个已经定义过的委托类型名称] [事件名称];

一个实例:

public event MyDelegate myEvent;(注意此处是类型对象,因此必须存在于class中)

针对该事件的操作:

myEvent = new MyDelegate(somFunc1) ; ----------> 编译错误,针对事件对象,该操作不被允许,然而普通委托是可以的。

myEvent += new MyDelegate(someFunc2);

myEvent -= someFunc2;

 

C#中的委托和事件这两个概念让我混淆了一段时间,网上看来的资料有的也让我更难理解。我只好自己来总结,首先这两个不是同一个层次的概念,委托(这里指delegate)是与class关键字同层次的,用于创建委托类型(这里指某个具体的类型,如上文的MyDelegate);事件是一种特殊的委托类型的实例对象,事件的创建必须依赖于某个预先定义好的符合一定要求的委托类型。如上文中的myEvent。

其次我觉得不便理解的是事件这个提法,事实上定义出来的事件是个委托类型的对象,它负责调用针对该事件的所有已经挂接到该委托下的函数。所以我认为称之为eventHandler更具可读性。而针对该对象的+=/-=操作只是在增加事件响应函数的数目而已。真正的触发事件的代码,是在其它地方,而且最终也就是以委托调用的形式出现。在我的概念中,事件一直是触发出来的,所以当我看到event这个关键词,以及对应的+=和-=操作后,就更难理解了。event这个关键词可以用,不过说明的时候还是习惯地叫它事件处理委托吧,这样定义才准确,至少更便于我理解。

 

附一个写的比较好的博文,供以后参考:

http://www.cnblogs.com/jimmyzhang/archive/2007/09/23/903360.html

 

------------------------------------------------

经过实验,需作一些修正,event并不对函数签名有所限制,只是提倡程序员使用类似于(object sender, XXEventArgs e)这样的参数列表,另外,事件处理的执行不创建新的线程,属于同步操作,所以对于一些耗时较长的操作还需要辅助以多线程机制为宜。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多