委托的應用之事件
阿新 • • 發佈:2017-05-23
con 代碼 eve null awake his 增加 del 問題: 總結
前言
上一個章節介紹了委托,這裏我們再通過一個例子繼續鞏固一下委托的用法並引入事件的用法 。
為了便於理解,這裏還是引入一個很老的例子:
因為一只貓叫了一聲 接著老鼠被嚇跑 小孩哭也了起來 最後媽媽也被吵醒。
下面用代碼來實現這些功能
1 /// <summary> 2 /// 貓類 3 /// </summary> 4 public class Cat 5 { 6 /// <summary> 7 /// 貓叫的方法 8 /// </summary>9 public void Miao() 10 { 11 Console.WriteLine("貓喵了一聲"); 12 13 new Mouse().Run(); 14 new Baby().Cry(); 15 new Mother().Awake(); 16 } 17 } 18 19 20 /// <summary> 21 /// 老鼠類 22 /// </summary> 23 public classMouse 24 { 25 /// <summary> 26 /// 老鼠跑的方法 27 /// </summary> 28 public void Run() 29 { 30 Console.WriteLine("老鼠開始跑"); 31 } 32 } 33 34 /// <summary> 35 /// 小孩類 36 /// </summary> 37 public class Baby 38 { 39 ///<summary> 40 /// 小孩哭的方法 41 /// </summary> 42 public void Cry() 43 { 44 Console.WriteLine("嬰兒哭了起來"); 45 } 46 } 47 48 /// <summary> 49 /// 媽媽類 50 /// </summary> 51 public class Mother 52 { 53 /// <summary> 54 /// 媽媽醒的方法 55 /// </summary> 56 public void Awake() 57 { 58 Console.WriteLine("媽媽被吵醒了"); 59 } 60 } 61 62 class Program 63 { 64 static void Main(string[] args) 65 { 66 { 67 //直接調用 68 new Cat().Miao(); 69 } 70 Console.ReadLine(); 71 } 72 }
代碼寫完了,功能完成了 。
那麽問題還是那個問題:耦合,依賴,不擴展,增加類的動作或者調整順序都會導致Cat類被修改。
為解決這一問題 還是用前面用的委托(上一章就是學習的委托的接解藕功能),
代碼如下:
在Cat類聲明一個委托
1 //這裏定義一個委托 2 public delegate void MiaoHandel(); 3 4 /// <summary> 5 /// 貓類 6 /// </summary> 7 public class Cat 8 { 9 /// <summary> 10 /// 貓叫的方法 11 /// </summary> 12 public void Miao() 13 { 14 Console.WriteLine("貓喵了一聲"); 15 } 16 }
外面再給委托添加後和刪除方法,還可以任意調整順序且不用修改Cat類。
class Program { static void Main(string[] args) { { //直接調用 new Cat().Miao(); } Console.WriteLine("--------------------------------"); { //用委托來調用 MiaoHandel miaoHandel=new MiaoHandel(new Cat().Miao); miaoHandel += new Mouse().Run; miaoHandel += new Baby().Cry; miaoHandel += new Mother().Awake; //還可以通過-=來刪除方法 miaoHandel -= new Mother().Awake; miaoHandel.Invoke(); } Console.ReadLine(); } }
說到這兒,那麽到底什麽是事件呢?
其實前面我講了委托是一個類,那麽事件就是委托的一個實例,加了一個event關鍵字。
那要說委托與事件的區別。本質上就是類跟實例的區別了。
來我們還是來看看代碼
先在Cat類定義一個事件
1 //這裏定義一個委托 2 public delegate void MiaoHandel(); 3 4 /// <summary> 5 /// 貓類 6 /// </summary> 7 public class Cat 8 { 9 /// <summary> 10 /// 貓叫的方法 11 /// </summary> 12 public void Miao() 13 { 14 Console.WriteLine("貓喵了一聲"); 15 } 16 17 public event MiaoHandel MiaoHandelEvent; 18 }
主程序裏面就用我們自己定義的委托的實例(事件)來調用
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 { 6 //直接調用 7 new Cat().Miao(); 8 } 9 Console.WriteLine("--------------------------------"); 10 { 11 //用委托來調用 12 Cat cat = new Cat(); 13 cat.MiaoHandelEvent = new MiaoHandel(new Cat().Miao); //報錯了:這裏不能直接賦值 14 cat.MiaoHandelEvent += new Mouse().Run; 15 cat.MiaoHandelEvent += new Baby().Cry; 16 cat.MiaoHandelEvent += new Mother().Awake; 17 //還可以通過-=來刪除方法 18 cat.MiaoHandelEvent -= new Mother().Awake; 19 cat.MiaoHandelEvent.Invoke(); //報錯了:這裏不能直接賦 20 } 21 Console.ReadLine(); 22 } 23 }
改成事件之後 ,我們會發現 事件是不能被賦值和調用的,這樣做的好處就是 出於安全性的考慮,可以控制權限,外面不能賦值/調用。
那麽要使用事件就必須在這個事件的發起者內部定義調用的方法。再來看看 修改之後最終的代碼
貓類的方法
1 namespace DelegateEventDemo 2 { 3 //這裏定義一個委托 4 public delegate void MiaoHandel(); 5 6 /// <summary> 7 /// 貓類 8 /// </summary> 9 public class Cat 10 { 11 /// <summary> 12 /// 貓叫的方法 13 /// </summary> 14 public void Miao() 15 { 16 Console.WriteLine("貓喵了一聲"); 17 } 18 19 public event MiaoHandel MiaoHandelEvent; 20 21 /// <summary> 22 /// 事件的調用方法 23 /// </summary> 24 public void MiaoHandelEventInvoke() 25 { 26 if (this.MiaoHandelEvent != null) 27 { 28 MiaoHandelEvent.Invoke(); 29 } 30 } 31 } 32 }
最終調用
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 { 6 //直接調用 7 new Cat().Miao(); 8 } 9 Console.WriteLine("--------------------------------"); 10 { 11 //用委托來調用 12 Cat cat = new Cat(); 13 cat.MiaoHandelEvent += new Cat().Miao; 14 cat.MiaoHandelEvent += new Mouse().Run; 15 cat.MiaoHandelEvent += new Baby().Cry; 16 cat.MiaoHandelEvent += new Mother().Awake; 17 18 cat.MiaoHandelEventInvoke(); 19 } 20 Console.ReadLine(); 21 } 22 }
總結
委托與事件的區別:
1. 委托是一個類型,事件就是委托的一個具體實例,加上一個event關鍵字
2. 委托可以直接賦值和調用。而事件不能直接被賦值和調用, 這是出於安全性的考慮。
委托的應用之事件