開啟新的讀書之旅,這次讀的書為《.Net之美:.Net關鍵技術深入解析》。 我是選擇性閱讀的,把一些自己覺得容易忘記的,或者比較重要的知識點記錄下來,以便以後能方便呢查閱。 尊重書本原作者,如果大家能有個可能的話,去看看這本書,作者寫得挺不錯的。例子和知識點各方面都寫挺不錯的。 本章的內容 什麼是委
開啟新的讀書之旅,這次讀的書為《.Net之美:.Net關鍵技術深入解析》。
我是選擇性閱讀的,把一些自己覺得容易忘記的,或者比較重要的知識點記錄下來,以便以後能方便呢查閱。
尊重書本原作者,如果大家能有個可能的話,去看看這本書,作者寫得挺不錯的。例子和知識點各方面都寫挺不錯的。
本章的內容
什麼是委托/創建委托類型的寫法/事件與委托/發佈者和訂閱者(觀察者模式)
什麼是委托:
說白了就是平時我們把變數當參數傳遞的時候,這個變數的類型可以是int類型,double類型,string類型以及各種自定義引用類型等等,但是有時候,我們需要的把一個方法當作參數傳入到另外方法中,這個時候就需要一個容器去存儲,這個時候該類型的名稱就是成為“委托”。
創建委托類型的寫法:
一個普通的方法名: public void NomalMenthod(string parameter)
一個方法的委托 : public delegate void MenthodDelegate(string parameter);
委托與方法有什麼不同呢,不同之處就是都了delegate進行修飾,以及不同的名稱而已,它們的共同點就是:相同的返回類型,相同的參數。其實,一個委托最終也是編譯成一個類。以下標出委托的寫法與用法:
public static void Main(string[] args) { //使用委托。傳入與委托相同類型的方法作參數 sayhi("豬豬豬扒",ChineseSay); Console.Read(); } //1.目的是一個問號的方法,但是各個國家的方式問好方法不相同,在代碼層面中需要一個這些方法共同的特點來做一個統一,所以把委托做一個參數 public static void sayhi(string name, MenthodDelegate delegatemethod) { delegatemethod(name); } //2.定義一個委托類型作為統一的方法的類型 public delegate void MenthodDelegate(string parameter); //3.1這兩步都是說明方法是動作不一樣而已。 public static void ChineseSay(string name) { Console.WriteLine("李好 " + name); } //3.2這兩步都是說明方法是動作不一樣而已。 public static void EnglishSay(string name) { Console.WriteLine("Morning " + name); }
創建一個委托(註意不是創建委托類型),為委托綁定方法,一個委托可以有綁定多個方法,委托的調用
public static void Main(string[] args) { //創建一個委托(傳入參數時已經綁定了一個委托了) MenthodDelegate m = new MenthodDelegate(ChineseSay); //為委托綁定第二個方法 m += EnglishSay; //委托的調用方式1 m.Invoke("我是參數"); //委托的調用方式2 m("我是參數"); //為委托取消方法的綁定 m -= EnglishSay; Console.Read(); }
事件與委托
事件就是對委托的封裝,如果在一個類中,委托聲明為privite,則不能暴露到給類外的,但是又不想該委托直接被賦值修改,所以這個時候就定義了事件。
定義事件的寫法:public event MenthodDelegate MenthodEvent;
事件就類似於定義個委托變數,只是多了public修飾符和event,在該類中外部,如果要訪問並註冊事件時,只能使用“+=”和“-=”。
類中的調用調用直接使用 MenthodEvent()或者MenthodEvent.Invoke()就可以了。
public class DelegateClass { //在類中封裝委托為事件 public event MenthodDelegate menthodevent; //調用事件 public void testdelegate(string name) { if (menthodevent != null) { menthodevent(name); } } } //在另外一個方法中調用 public static void Main(string[] args) { DelegateClass dc = new DelegateClass(); //註冊事件 dc.menthodevent += EnglishSay; dc.testdelegate("我是參數"); Console.Read(); }
發佈者和訂閱者(觀察者模式)
發佈者表示發佈事件的代碼,就是供訂閱者在事件上使用+=來註冊事件的一方,通俗一點的意思就是:發佈事件的代碼;訂閱者就是訂閱事件的一方,就是使用+=中右邊的方法,理解為訂閱事件的代碼;
如果沒有事件event進行封裝,那麼在類的外部,創建了類的對象後,可以隨意觸發事件,對於訂閱事件來說是一件極其不利的事件,所以事件更好地實現了發佈者和訂閱者的模式。
至今我還是覺得觀察者模式和發佈者模式一個概念,只是說法上不一樣而已,觀察者就是訂閱事件的人,而被觀察者就是發佈事件的人.
Observer設計模式:Observer設計模式是為了定義對象間的一種一對多的依賴關係,以便於當一個對象的狀態改變時,其他依賴於它的對象會被自動告知並更新。Observer模式是一種松耦合的模式.
觀察者模式:
public static void Main(string[] args) { //被觀察者 Heater heater = new Heater(); //註冊事件 heater.Boiled += (new ConsoleApplication1.Alarm()).MakeAlert; heater.Boiled += (new ConsoleApplication1.Display()).ShowMsg; //就是此觸發事件的 heater.BoilWater(); Console.Read(); } public class Heater { public string type = "RealFire 001"; public string area = "China Xian"; private int temperture;//水溫 public delegate void BoiledEventHandler(Object sender, BoiledEventArgs s); public event BoiledEventHandler Boiled; //3.在觀察對象想傳遞它自身屬性屬性給觀察者,這時候就需要另外構建一個參數類型,就是此類型了. public class BoiledEventArgs : EventArgs { public readonly int temperature; public BoiledEventArgs(int temperature) { this.temperature = temperature; } } //2.這裡是執行觸發的事件操作的代碼 protected virtual void OnBoiled(BoiledEventArgs e) { if (Boiled != null) { Boiled(this, e); } } //1.此方法是被觀察對象的觸發事件的代碼,在什麼情況下觸發事件由此方法決定 public virtual void BoilWater() { for (int i = 0; i < 100; i++) { temperture = i; if (temperture > 95) { //構造參數-->分別為第3步 BoiledEventArgs args = new BoiledEventArgs(temperture); //調用操作委托的方法--->第2步 OnBoiled(args); } } } } //觀察者1 public class Alarm { /// <summary> /// 觀察者需要執行的方法的參數由觀察對象提供 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void MakeAlert(Object sender,Heater.BoiledEventArgs e) { Console.WriteLine("現在" + e.temperature + "度"); } } //觀察者2 public class Display { /// <summary> /// 觀察者所需要做的操作 /// </summary> /// <param name="sender"></param> /// <param name="e">類型由觀察對象提供,參數對象只需要獲取可以了</param> public void ShowMsg(Object sender, Heater.BoiledEventArgs e) { Console.WriteLine(" Display: 水快開了, 當前溫度:{0} 度。", e.temperature); } }
以上就是觀察者模式以及一些自我的瞭解,.net自帶的委托寫法也是按照以上的格式.其中一些規範如下:
- 委托類型的名稱都應該以EventHandler結束。
- 委托的原型定義有一個void返回值,並接受兩個輸入參數:一個Object類型,一個EventArgs類型( 或繼承自 EventArgs)
- 事件的命名為委托去掉EventHandler之後剩餘的部分。
- 傳入事件的參數的應該繼承自EventArgs,並且以此結尾.
我是把委托簡單理解為4種操作。
1.創建委托類型
2.創建委托變數(封裝了就叫事件)
3.為委托變數註冊方法
4.委托的調用
5.直接把方法當作參數使用