zoukankan      html  css  js  c++  java
  • 委托与事件

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

      参考网址: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,也只能在所属类的内部触发,而类外部只能订阅不能触发事件。


    总结                             

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

    欢迎添加我的公众号一起深入探讨技术手艺人的那些事!

    如果您觉得本文的内容有趣就扫一下吧!捐赠互勉!
      

  • 相关阅读:
    tab选项卡
    为什么不高兴呢
    #pragma INITCODE 是什么意思
    驱动开发基础知识
    Windows的驱动开发模型
    分页内存和非分页内存区别
    WDF驱动模型
    博客启动描述
    struct和typedef struct
    数据解析代码
  • 原文地址:https://www.cnblogs.com/fsjohnhuang/p/2325839.html
Copyright © 2011-2022 走看看