.Net之美讀書系列(一):委託與事件

開啓新的讀書之旅,此次讀的書爲《.Net之美:.Net關鍵技術深刻解析》。設計模式

我是選擇性閱讀的,把一些本身以爲容易忘記的,或者比較重要的知識點記錄下來,以便之後能方便呢查閱。this

尊重書本原做者,若是你們能有個可能的話,去看看這本書,做者寫得挺不錯的。例子和知識點各方面都寫挺不錯的。spa

本章的內容.net

什麼是委託/建立委託類型的寫法/事件與委託/發佈者和訂閱者(觀察者模式)設計

什麼是委託:code

說白了就是平時咱們把變量當參數傳遞的時候,這個變量的類型能夠是int類型,double類型,string類型以及各類自定義引用類型等等,可是有時候,咱們須要的把一個方法看成參數傳入到另外方法中,這個時候就須要一個容器去存儲,這個時候該類型的名稱就是成爲「委託」。server

建立委託類型的寫法:對象

一個普通的方法名:  public  void NomalMenthod(string parameter)blog

一個方法的委託   :  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.直接把方法看成參數使用

相關文章
相關標籤/搜索