漫谈委托和事件

      委托和事件是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             else
39             {
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希望这篇漫谈对您有所帮助。

原文地址:https://www.cnblogs.com/cnDqf/p/4077136.html