首页 > 代码库 > 漫谈委托和事件

漫谈委托和事件

      委托和事件是C#中相当重要的部分,先简单科普一下这两个概念的定义:

      委托delegate 关键字用于声明一个引用类型,该引用类型可用于封装命名方法或匿名方法。委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。——msdn

      事件event是特殊类型的多路广播委托,仅可从声明它们的类或结构(发行者类)中调用。 如果其他类或结构订阅了该事件,则当发行者类引发该事件时,会调用其事件处
理程序方法。事件可标记为 public、private、protected、internal 或protectedinternal。 这些访问修饰符定义类的用户访问事件的方式。——msdn

      估计能真正理解这两段话的都是大牛,我辈菜鸟只能“噢,原来如此,还是不懂...”最近菜鸟D在项目中使用到了委托,刚好有大牛路过,就请他帮忙诊断一下。

代码简化如下:

 1 namespace abc{ 2  3      public delegate void xxxdelegate();//委托的声明 4      5      class abc 6     { 7           public xxxdelegate xxx; 8  9         public void a()10         {11         }12 13         public void b()14         {15         }16 17         public void c()18         {19         }20 21         public void main()22         {23             ...24             pd();25             xx();26         }27 28         public void pd()29         {   30              if ()31             {32                 xxx = a;33             }34             else if ()35             {36                 xxx = b;37             }38             else39             {40                 xxx = c;41             }42         }43 44         public void xx()45         {46             ...    47             xxx();48         }49     }50 }

      大牛看完代码,皱了皱眉头,“委托不是这么用的啊...”

      “委托不是一个安全的函数指针,可以把方法当成变量来使用的么?”菜鸟D不解。

      “这么理解委托是不错的,但是它的应用场景不对啊,这些都是自己的方法,为什么不用一个判断,把判断的逻辑封装成方法,直接调用方法呢?这样看,你的委托是不是没有什么用?”大牛很耐心,“委托,委托,顾名思义应该执行的是别人的方法呀 。”

     菜鸟D无话可说了,因为这么写只是在用“指针”的思想,而委托的本意却是被抛在了一边,“那么,委托的应用场景应该是什么?”。

    “委托通常在处理异步线程时才会使用,而且它也是事件的基础。委托定义一种类型,事件可以看做这种类型的一个变量,你在反编译时也肯定见过,事件会被反编译成一个私有的委托以及 +=和-= 两个共有的方法供外部来使用。所以它的使用场景就很明显了,使用事件的时候,异步线程调用的时候。我建议你看看设计模式中的订阅发布模式。”

     菜鸟D找了一下资料,发现各种资料说的乱七八糟,就在这时大牛给了一个很简单的例子,他指着电脑的USB口,“我不知道这里会插入什么设备,但是我定义了一个规格,只要符合这个规格,就可插进来。事件也是这样,假设是一个button,我不知道点击它会有什么效果,我就给它(button)封装一个点击事件,你只需要在外部注册这个事件,就可以让它在点击时有你想要的效果。spring的依赖注入也是这么回事,那个经常通过接口来注入,这个则是通过事件这个‘接口’或者叫‘插口’来实现,事件的内部又是委托,其实就是这么个关系。”

     菜鸟D仔细想了想,结合原来的经验——在模态对话框或者主窗体和子窗体(并非是继承关系的父子窗体,而是由主窗体创建的)之间通信时会出现委托,至于上面代码的“指
针”确实是个笑话。

    总结:委托的使用场景:异步进程和事件的使用。
            订阅者模式:如果不太懂,可以参阅:http://blog.csdn.net/tjvictor/article/details/5223309
            spring的依赖注入思想到下一篇再写,不好意思了。

    菜鸟D希望这篇漫谈对您有所帮助。

漫谈委托和事件