前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >委托与事件

委托与事件

作者头像
^_^肥仔John
发布2018-01-18 11:17:58
8460
发布2018-01-18 11:17:58
举报

  首先多谢网上的大牛们无私地分享自己的经验,让我这样的小鸟能站在巨人的肩膀上不断前进!

  参考网址:http://www.knowsky.com/395937.html(参考1)

http://hi.baidu.com/zhangguilin/blog/item/9d34dc17a088ff0ac83d6d08.html(参考2)

http://www.chinaz.com/program/2009/1014/94676.shtml(参考3)

  以下是我的总结:

委托                                                                    

  msdn把委托描述为面向对象、类型安全、可实现多播的函数指针。

  1、面向对象:.net把委托(函数指针)定义为类型,具体的类名为委托名称,并且存在继承关系:自定义委托<--System.MulticastDelegate<--System.Delegate。

  2、类型安全:委托对象中有_target、_methodPtr、_methodPtrAux三个变量。当委托实例指向某个实例方法时,_target指向实例对象,_methodPtr指向实例方法的JIT STUB(如果经过了JIT编译,就直接指向实例方法的内存地址),_methodPtAux为0;当委托实例指向某个静态方法时,_target指向委托实例本身,_methodPtr指向STUB(一小段代码,用于让CLR把_target设为null),_methodPtAux指向静态方法的内存地址。从上面可以看出委托实例中不仅保存了函数的地址,还保存了函数所在类的实例,相反看一下C++的函数指针只是保存函数的地址,而不管实例函数属于哪一个类。

  3、可实现多播:通过+=、—=添加(移除)函数指针。实例化委托时,MyDelegate d = new MyDelegate(my)为单播形式;MyDelegate d += new MyDelegate(my),d += new MyDelegate(my1)为多播形式。添加(移除)函数指针实际调用了MulticastDelegate的CombineImpl方法把函数指针添加到_invocationList(类型为object数组),可以同过委托实例.GetInvocationList()方法获取。

  注意:在多播情况,假如某些函数有返回值,那么要使用下列方式来获取返回值。

代码语言:javascript
复制
foreach(var item in 委托实例.GetInvocationList())
{
   item();
}

并非像(参考2)里面说的多播中的函数不能有返回值。

事件                               

  事件跟委托有许多相似之处,经常不知道使用哪一个,这里着重说明两者的区别。这里参考了.NET委托: 一个C#睡前故事,这个例子描述得十分清楚。

  下面是自己的总结。

  委托对象定义为public后不仅所属类内部能调用,类外部也能调用;事件不管即使定义为public,也只能在所属类的内部触发,而类外部只能订阅不能触发事件。

总结                             

  使用事件可以降低耦合度,事件的触发与事件的订阅分离,让感兴趣的对象订阅某个对象的全部或部分事件。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2012-01-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档