根據上篇博文的反響我想向大家說明,因為本人時間有限加上才疏學淺,無法寫出面面俱到的博文。我只是把自己經歷的覺得有些意義的技術點分享出來,希望大家見諒。當然,我不會讓大家走上歧途的。所有示例都是親測。
今天我想討論一下事件與委托之間的聯系。很多人說,事件即委托。真的是這樣嗎?那么微軟為何又要定義事件與委托兩個概念呢?
其實事件即委托,在我看來不如這樣解釋:事件是封裝過的委托實例。也就是說,事件是面向對象的產物,它是封裝性比較典型的示例。
首先我們來看一下事件的定義以及調用:
//定義委托 public delegate int MathHandle(int a, int b); public class Test { //定義事件 public event MathHandle MathEvent; public int Add(int a, int b) { return a + b; } public void Operation(int a, int b) { Console.WriteLine(this.MathEvent(a, b)); } } [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { Test t = new Test(); //為事件方法隊列添加方法 t.MathEvent += new MathHandle(t.Add); t.Operation(1,2);//此處如果調用t.MathEvent(1,2)會編譯錯誤; } }
執行結果:
我們再看看,如果我們將使用委托來實現上述方法:
//定義委托 public delegate int MathHandle(int a, int b); public class Test { public MathHandle MathEvent; public int Add(int a, int b) { return a + b; } } [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { Test t = new Test(); //為委托隊列添加方法 t.MathEvent += new MathHandle(t.Add); Console.WriteLine(t.MathEvent(1, 2));//委托可以直接在實例外部執行。 } }
執行結果:
從上面示例我們看到,同一個方法你可以使用委托來調用,你也可以使用事件來調用。那究竟有何不同?
其實事件就是一個狹義的委托,也就是事件是一個用於事件驅動模型的專用委托.你可以在客戶代碼中直接調用委托來激發委托指向的函數,而事件不可以,事件的觸發只能由服務代碼自己觸發。也就是說在你的代碼里委托你不但可以安排誰是它的調用函數,還可以直接調用它,而事件不能直接調用,只能通過某些操作觸發。除此之此,事件擁有委托的所有功能,包括多播特性。即事件可以有多個事件處理函數,委托同樣也可以是個多播委托.
希望能從這個小小的示例,向大家傳達到事件與委托的區別。
下面再貼一個稍微復雜的示例:
public class Heater { private int temperature; public void BoilWater() { for (int i = 1; i <= 100; i++) { temperature = i; if (temperature > 95 && BoilEvent != null) { //執行委托,無需知道要執行哪些方法 BoilEvent(temperature); } } } public delegate void BoilHandle(int param); public event BoilHandle BoilEvent;//封裝了委托 } public class Alarm { public void MakeAlert(int param) { Console.WriteLine("Alarm:水溫已經超過{0}度.",param); } } public class Display { public void ShowMsg(int param) { Console.WriteLine("Display:水已燒開,當前溫度{0}度.", param); } } [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { Heater heater = new Heater(); Alarm alarm = new Alarm(); heater.BoilEvent += alarm.MakeAlert; heater.BoilEvent += new Display().ShowMsg; heater.BoilWater(); } }
更多WEB開發技術請加群:Asp.Net高級群 號碼:261882616 博主以及同事和你共同探討感興趣的話題。