前面一章學習了委託以及多播委託,接下來咱們來學習下委託事件。學習
在學習委託事件的前提下,得知道什麼是觀察者模式。spa
首先,咱們來模擬一個場景:例如,當一隻狗汪汪汪叫的時候,baby被嚇哭了,恰好要偷東西的小偷被嚇跑了。code
咱們一慣的思惟是:建立三個類,分別寫一個方法表示他們的動做,當狗叫的時候,分別調用。代碼以下:blog
public class Dog { public static void Wang() { Console.WriteLine("狗汪汪汪汪"); Baby.Cry(); Thief.Run(); } } public class Baby { public static void Cry() { Console.WriteLine("baby被嚇哭了"); } } public class Thief { public static void Run() { Console.WriteLine("小偷跑了"); } } class Program { static void Main(string[] args) { Dog.Wang(); Console.Read(); } }
這樣作是能夠獲得咱們想要的結果,可是,Dog類與Baby、Thief之間的耦合就很緊了,不利於後期維護擴展。當咱們後期需求變更,要再添加一個動做:貓也被嚇的跑掉了。事件
怎麼辦,難道咱們還要去改動Dog類裏Wang方法的代碼嘛?這明顯是一個糟糕的事情。不過老是有辦法解決的,畢竟辦法都是人想出來的。string
上一個章節咱們知道了多播委託,就是把多個方法綁定到同一個委託,而後依次執行。it
接下來咱們來看看怎麼實現。event
一、首先咱們得聲明一個委託,而且建立這個委託的實例。class
二、當狗叫的時候,咱們來調用這個委託。擴展
三、當咱們調用狗叫以前,將要觸發的一系列動做(也就是觀察者的動做)綁定到委託就好了。
這3個步驟的代碼以下:
public delegate void DogWang(); public class Dog { static DogWang DogWangHandler; public static void Wang() { Console.WriteLine("狗汪汪汪汪"); if (DogWangHandler != null) DogWangHandler.Invoke(); } } class Program { static void Main(string[] args) { Dog.DogWangHandler = new DogWang(Baby.Cry); Dog.DogWangHandler += Thief.Run; Dog.Wang(); Console.Read(); } }
貼一下結果吧。
沒毛病。講到這裏,恍然大悟了,這樣的話,咱們後需求添加多少個動做都不要緊,咱們只須要將方法綁定(+=)給委託就行。固然也是能夠取消(-=)某一個動做的。
接下來咱們就要開始講事件了,
那麼什麼是事件呢?什麼是委託呢,它們以前又是什麼關係呢?我想這個問題確定有不少人想知道,也有不少人搞不清楚。
咱們知道委託是一種類型,而事件就是委託一個實例 。其實就是這麼簡單的。
咱們將上面的代碼用事件來實現,看看是什麼樣的。
public delegate void DogWang(); public class Dog { public static DogWang DogWangHandler; public static event DogWang DogWangHandlerEvent;//事件的本質就是委託的一個實例。加了event關鍵字 public static void Wang() { Console.WriteLine("狗汪汪汪汪"); if (DogWangHandlerEvent != null) DogWangHandlerEvent.Invoke(); } } class Program { static void Main(string[] args) { Console.WriteLine("==============事件實現================"); Dog.DogWangHandlerEvent += Baby.Cry; Dog.DogWangHandlerEvent += Thief.Run; Dog.Wang(); Console.Read(); } }
結果以下:
結果和上面同樣,這是就委託事件。那麼委託與事件調用有什麼不同呢?
一、事件不能像委託同樣 Dog.DogWangHandler = new DogWang(Baby.Cry); 被這樣初始化。由於委託能夠 Dog.DogWangHandler = null; ,用事件是爲了避免能在外部隨隨便便地將委託給 null 。
二、事件不能像委託同樣在外部調用 Dog.DogWangHandler(); ,這樣是爲了調用者不能想調用就調用。爲了防止當觸發一個件事,執行到一部分的時候就來調用。
小結一下:其實它們以前的區別就是一個權限問題。