C#中委托、事件和回调函数区别与联系

 

C#中委托、事件和回调函数的理解


在C#中我们经常会碰到事件,尤其是在WPF或者WinForm中,窗体加载、或者点击一个按钮,都会触发事件。实际上,事件是对委托的封装。如果不进行封装,让委托暴露给调用者,调用者就可以把委托变量重新引用到新的委托对象,也就删除了当前要调用的方法列表;更糟糕的是,公共的委托成员打破了封装不仅导致代码难以维护和调试,而且会导致应用程序有安全风险。下面分别说明。

1、委托

委托可以理解为一种协议。委托,是什么意思呢?举个例子,你碰到一件事,你需要让别人来帮你做(可能你还有别的事情要做),这就是委托,把你现在不能做的事让别人去做。为什么说委托就像一个协议呢,因为你不想把事情搞砸了,所以你“委托”的这个人做的这件事,你需要给他定一个标准。在C#中就是给所委托的对象定义好签名,参数有几个,分别是什么类型,委托方法需要反馈给你什么东西(或者不反馈)。从这种意义上理解,委托就像是一种协议。下面是例子。

[c#]  view plain  copy
  1. public delegate int MyDelegate(int x, int y);  
  2.     class Delegate_Demo {  
  3.         static void Main(string[] args) {  
  4.             //实例化被委托者  
  5.             Helper helper = new Helper();  
  6.             //创建委托对象  
  7.             MyDelegate myDele = new MyDelegate(helper.Add);  
  8.             int sum = myDele(1, 2);  
  9.             Console.WriteLine(sum);  
  10.         }  
  11.   
  12.     }  
  13.     class Helper {  
  14.         public Helper() {}  
  15.   
  16.         public int Add(int num1, int num2) {  
  17.             return num1 + num2;  
  18.         }  
  19.     }  

上述例子中public delegate int MyDelegate(int x, int y);声明了一个委托,告诉被委托者这件事你要这么干,我给你两个整数,你计算他们的和,怎么计算我不管,计算完之后你把和给我。

2、事件

在某件事情发生时,一个对象可以通过事件通知另一个对象。比如,前台界面一个求和按钮被点击了,他通知你,可以把a和b这两个数相加了。这就是一个事件。可以看出事件是在一个时间节点去触发另外一件事情,而另外一件事情怎么去做,他不会关心。就事件来说,关键点就是什么时候,让谁去做。

在编译器处理event关键字时,会自动提供注册和注销方法以及任何必要的委托类型成员变量(私有的),因此不能从触发事件的对象去调用它们,event关键字就像一个语法糖,节省了我们打字的时间。

定义一个事件有两步,首先定义一个委托,它包括了这件事的“协议”和委托方法(由谁去做);其次,用event关键字和相关委托声明这个事件。事件像是一个接口,封装了委托所定的“协议”。由于委托已经定义了协议,剩下的就是按这个协议去办事,至于怎么做它并不关心。下面是一个例子。

[c#]  view plain  copy
  1. public delegate int MyDelegate(int x, int y);  
  2.     class Delegate_Demo {  
  3.         //声明事件  
  4.         static event MyDelegate myEvent;  
  5.         static void Main(string[] args) {  
  6.             //交代事件  
  7.             myEvent += new Helper().Add;  
  8.             int sum = myEvent(3, 4);  
  9.             Console.WriteLine(sum);  
  10.         }  
  11.   
  12.     }  
  13.     class Helper {  
  14.         public Helper() {}  
  15.   
  16.         public int Add(int num1, int num2) {  
  17.             return num1 + num2;  
  18.         }  
  19.     }  

从上面可以看出,调用者无法访问委托对象。

3、回调函数

回调函数就是把一个方法的传给另外一个方法去执行。回调函数只是一个功能片段,由用户按照回调函数的调用约定来实现的一个函数。先看一个例子。

[c#]  view plain  copy
  1. public delegate int MyDelegate(int x, int y);  
  2.     class Delegate_Demo {  
  3.         //声明事件  
  4.         static event MyDelegate myEvent;  
  5.         static void Main(string[] args) {  
  6.   
  7.             int sum = MyAdd(1, 2, new Helper().Add);  
  8.             Console.WriteLine(sum);  
  9.         }  
  10.         private static int MyAdd(int a, int b, MyDelegate myDele) {  
  11.             return myDele(a, b);  
  12.         }  
  13.   
  14.     }  
  15.     class Helper {  
  16.         public Helper() {}  
  17.   
  18.         public int Add(int num1, int num2) {  
  19.             return num1 + num2;  
  20.         }  
  21.     }  

可以看出,可以把任意一个符合这个委托的方法传递进去,意思就是说这部分代码是可变的。而设计上有一个抽离出可变部分代码的原则,这种用法无疑可以用到那种场合了。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值