委托与事件

简介:

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

  参考网址: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()方法获取。

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

foreach(var item in 委托实例.GetInvocationList())
{
   item();
}

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

 

事件                               

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

  下面是自己的总结。

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


总结                             

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

目录
相关文章
|
2月前
|
C#
C#一分钟浅谈:委托与事件的实现方式
本文详细介绍了C#编程中委托与事件的基础知识及应用场景。首先解释了委托的概念,包括定义与使用方法;接着介绍了事件这一基于委托的特殊类型,展示了如何在类中定义事件及跨类订阅与处理事件;最后讨论了常见问题如事件未处理异常、重复订阅及内存泄漏等,并提出了相应的解决方案。通过本文,读者将全面掌握委托与事件的使用技巧,提升应用程序的设计与开发水平。
109 7
|
6月前
|
存储 安全 C#
C# - 委托与事件
这篇文档介绍了C#中的委托和事件。委托是存储方法引用的类型,支持回调、事件处理,具有引用方法、类型安全、多播性等特性,并在异步编程中发挥作用。事件是委托的封装,提供保护和订阅机制,防止外部直接访问。当需要在类内部控制方法调用,防止外部误触发时,可使用事件。
|
C#
C# 委托和事件
C# 委托和事件
98 0
C# 委托和事件
|
C# 设计模式 编译器
|
Web App开发 安全 C#
|
监控 C# Windows