.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.直接把方法當作參數使用

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM