亲而有间,密而有疏;和而不同,美美与共

C#委托与事件--后续补充

委托、事件补充

针对昨天文章
http://www.cnblogs.com/joeymary/p/8486358.html

委托:让方法可以跟简单对象一样作为参数进行传递,也就是将方法作为参数进行封装。
方法:本质就是代码段

其实也好理解,目的就是为了封装,多态,既然简单对象如int i可以做为参数传递,那么语句代码段应该也可以作为参数传递。

委托之于方法就像父类之于子类
委托就是一个抽象化的方法类型定义
(目的也是为了方便方法作为参数传递,这样想,又有点泛型的感觉)

简单对象抽象一次出现了类型
简单类型抽象一次出现了泛型
简单方法抽象一次出现了委托

委托在IL中实际上就是一个class

委托链与多播委托

委托链

public delegate void MyDelegate();

public static void test()
{
    MyDelegate d = null;
    MyDelegate d1 = new MyDelegate(obj.Method);
    MyDelegate d2 = new MyDelegate(obj.Method);
    d += d1;
    d += d2;
}

多播委托

public delegate void MyDelegate();

public static void test()
{
    MyDelegate d = null; 
    d += obj.Method;
    d += obj.Method;
}

如果上述理解没错的话,再加上我简单的测试了下,Add watch两个d,委托d的GetInvocation是一致的,那么所谓委托链跟多播委托在上述的用法上的没区别的。

委托链包装的方法会顺序被执行,如果委托链中被调用的委托抛出一个异常,这样链中的后续所有对象都不会被调用。

直接调用这个委托链(委托链本身就是个委托)委托的返回值为非void的话,只有最后一个返回值会被保留,之前的都舍弃。

若需解决上述问题,通过调用Delegate.GetInvocation方法来获取委托链对象数组,显示调用链中的每一个委托。

Delegate.GetInvocation返回一个Delegate引用构成的数组,注意是引用,数组中的每个对象指向一个委托对象。而指向的这个委托对象又可以有自己的委托引用数组,一直下去,形成一条委托链,是不是有点类似js的原型链

委托变量可以在定义该委托变量的类外部直接调用和用=赋值,一旦向类外部公开(委托变量修饰符为public)委托变量,什么时候调用这个委托变量,你是无法控制的。

事件则不同,在定义事件变量的类外部只能添加或移除处理程序(方法,本质也是委托),而事件在什么时候,什么条件下执行只能在定义事件变量的类内部定义。

事件可看作委托的一个特殊实例。叫实例貌似不太恰当,因为事件本身没有方法挂载,也就是没有实现。叫“子委托” 或许合适点,因为委托其实就是class,那么事件叫委托的“子类”也未尝不可。

事件之于委托貌似又类似属性之于字段
+= -=对应于get set

欢迎讨论~
感谢阅读~

个人公众号:

原文:http://www.cnblogs.com/joeymary/p/8490198.html

posted @ 2018-03-01 19:07  大兄弟竹子  阅读(655)  评论(0编辑  收藏  举报