博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
委托(5)委托和事件
阅读量:5918 次
发布时间:2019-06-19

本文共 3323 字,大约阅读时间需要 11 分钟。

  在面试的时候经常会被问到,委托和事件的联系和区别?之前也一直没有彻底搞明白,下面就来总结一下。

从一个有趣的需求入手。有三个角色,猫,老鼠和主人,当猫叫的时候,老鼠开始逃跑,主人则从睡梦中惊醒。

使用事件实现

如下代码:

1 namespace ConsoleApplication4 2 { 3     class Program 4     { 5         static void Main(string[] args) 6         { 7             Cat cat = new Cat("猫"); 8             Mouse mouse1 = new Mouse("老鼠", cat); 9             Master master = new Master("张三", cat);10             //猫叫,通知所有订阅者11             cat.CatCry();12 13             Console.ReadKey();14         }15     }16 17     #region 猫18     public class Cat19     {20         private string name;21 22         //声明事件23         public event EventHandler
CatCryEvent;24 25 public Cat(string name)26 {27 this.name = name;28 }29 30 public void CatCry()31 {32 //声明事件参数33 CatCryEventArgs args = new CatCryEventArgs(name);34 Console.WriteLine(args);35 36 //触发事件37 CatCryEvent(this, args);38 }39 }40 41 ///
42 /// 事件参数43 /// 44 public class CatCryEventArgs : EventArgs45 {46 private string catName;47 48 public CatCryEventArgs(string catName)49 : base()50 {51 this.catName = catName;52 }53 54 public override string ToString()55 {56 return string.Format("{0}叫了", catName);57 }58 }59 #endregion60 61 #region 老鼠62 public class Mouse63 {64 private string name;65 public Mouse(string name, Cat cat)66 {67 this.name = name;68 cat.CatCryEvent += CatCryEventHandler;//本质上就是往委托链中添加一个方法69 }70 71 //事件处理程序72 private void CatCryEventHandler(object sender, CatCryEventArgs e)73 {74 Console.WriteLine("{0}逃走了:我勒个去,赶紧跑啊!", name);75 }76 }77 #endregion78 79 #region 主人80 public class Master81 {82 private string name;83 public Master(string name, Cat cat)84 {85 this.name = name;86 cat.CatCryEvent += CatCryEventHandler;//本质上就是往委托链中添加一个方法87 }88 89 //事件处理程序90 private void CatCryEventHandler(object sender, CatCryEventArgs e)91 {92 Console.WriteLine("{0}醒了:我勒个去,叫个锤子!", name);93 }94 }95 #endregion96 97 }

 

通过demo可以总结:

1,定义和使用事件的流程,如下图:

2,定义事件参数要继承EventArgs,定义事件使用public event EventHandler<CatCryEventArgs> CatCryEvent;

3,事件使用了观察者模式,有发布,订阅和通知,至于怎么实现的,本质是什么下面会总结到。

使用委托实现

1 namespace ConsoleApplication5 2 { 3     //声明委托 4     public delegate void Del1(); 5  6     class Program 7     { 8         static void Main(string[] args) 9         {10             //创建委托链(链式委托)11             Del1 del1 = () => Console.WriteLine("猫叫了");12             del1 += () => Console.WriteLine("老鼠逃走了:我勒个去,赶紧跑啊!");13             del1 += () => Console.WriteLine("主人醒了:我勒个去,叫个锤子!");14 15             //调用委托16             del1();17 18             Console.ReadKey();19         }20 21     }22 }

 

 可以看出,其实就是一个链式委托的调用。向链式委托添加了三个方法,调用的时候依次执行。

事件和委托

为了弄清彻底弄清事件和委托的关系,我们查看下EventHandler的源代码,如下图。

看到上图的红色标记了吗?所以,事件是基于委托实现的。总结一下:

联系:

1,事件是基于委托实现的,可以通俗地理解为:事件是一种特殊的委托,特殊的地方在于它定义的是一个有两个参数(事件源和事件参数)没有返回值的委托。

2,当事件的订阅者订阅事件时,本质上是将事件的处理方法加入到委托链中,当事件触发时,委托链中的所有事件处理方法都会被调用。

 

区别:

委托本质是一种自定义类型(class),而事件本质是一个特殊的委托实例(对象)。

 

转载地址:http://osfvx.baihongyu.com/

你可能感兴趣的文章
SQL Server 2016 Failover Cluster + ALwaysOn
查看>>
不疯魔,不成活!——二叉树的创建、遍历(递归实现)等操作。
查看>>
Xilinx Zynq-7000 嵌入式系统设计与实现
查看>>
Axure教程
查看>>
myeclipse开启后卡死、building workspace缓慢 问题解决
查看>>
php信息导航栏的代码编写
查看>>
[转载]斐讯K2 A2版免TTL刷BREED不死Bootloader
查看>>
[转载]WinRAR 3.8中文版 注册码
查看>>
二十八 错误、调试和测试
查看>>
js实现读秒
查看>>
HTML5
查看>>
文本域防止拖拽或者取消边框的做法
查看>>
如何监控wifi,3g,gps的流量
查看>>
I.MX6 bq27441 GPOUT interrupt
查看>>
Android 系统 reboot
查看>>
python2升级到python3 yum不可用解决方案
查看>>
手机端白屏前端优化的方法,5 种以上
查看>>
【转】如何把Json格式字符写进text文件中
查看>>
【BZOJ1703】【usaco2007margold】ranking the cows 奶牛的魅力排名
查看>>
浏览器 页面报错
查看>>