在面試的時候常常會被問到,委託和事件的連結和區別?之前也一直沒有徹底搞明白,下面就來總結一下。
從一個有趣的需求開始。有三個角色,貓,老鼠和主人,當貓叫的時候,老鼠開始逃跑,主人則從睡夢中驚醒。
如下程式碼:
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<CatCryEventArgs> 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 /// <summary>42 /// 事件参数43 /// </summary>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,定義事件使用publicevent EventHandler#
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),而事件本質是一個特殊的委託實例(物件) 。
#
以上是總結委託和事件的聯繫和區別的詳細內容。更多資訊請關注PHP中文網其他相關文章!