委托、事件补充
针对昨天文章
委托:让方法可以跟简单对象一样作为参数进行传递,也就是将方法作为参数进行封装。
方法:本质就是代码段
其实也好理解,目的就是为了封装,多态,既然简单对象如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
欢迎讨论~
感谢阅读~
个人公众号: