委託與事件-事件詳解(二)

小世界的野孩子發表於2019-07-20

前言

  上一節我們瞭解學習了委託,委託是型別安全的類,它定義了返回型別和引數的型別。委託類不僅包含對方法的引用,也可以包含對多個方法的引用。

  理解委託的一種好的方式是把委託視為是給方法的簽名和返回型別指定名稱。

  今天我們繼續來了解委託和事件,現在我們來了解學習一下事件詳解。

事件

  事件基於委託,為委託提供了一種釋出/訂閱機制,在.Net中隨處可見到這種事件,例如在應用程式中,Button類提供了Click事件,這類事件就是委託。

  既然事件是為委託提供了釋出/訂閱機制,那麼肯定設計到兩個角色,釋出者以及訂閱者。

  事件釋出者(Publisher)--事件的釋出者就是一個物件,這個物件維護自身的狀態資訊,一旦自身的狀態資訊發生了改變,那麼便觸發一個事件

  事件訂閱者(Subscriber)--對事件感興趣的物件,也可以叫做Receiver,可以註冊感興趣的事件,在觸發一個事件後自動執行這段程式碼。

  到底事件的一個怎麼執行過程呢?在介紹此過程中我們先看下委託與事件的微軟編碼規範吧。

    一、上一節講了委託的命名需以EventHandler結束

    二、委託原型的定義是一個void返回值而且有兩個引數,一個object型別,一個EventArgs型別(或者繼承此型別的)

    三、事件的命令是委託去掉字尾EventHandler

    四、繼承了EventArgs需以EventArgs結尾

  下面我們一起來看一個簡單的委託與事件案例

委託與事件簡單例項講解

  假設現在電信公司提供一個話費流量查詢的功能,但是其中小明僅關心流量,小紅僅關心話費,小李關心話費和流量。現在設計一段他們查詢流量和話費的功能。

  分析下,他們關心感興趣的是流量多少,話費多少。--訂閱者

  輸入查詢觸發事件,反饋流量多少,話費多少。--釋出者

    

    /// <summary>
    /// 所有訂閱者(Subscriber)感興趣的物件,本列中訂閱者感興趣的物件是流量話費及多少
    /// </summary>
    public class PubEventArgs : EventArgs
    {
        /// <summary>
        /// 話費或者流量具體值
        /// </summary>
        public readonly string mobleType;
        public PubEventArgs()
        {


        }
        public PubEventArgs(string mobleType)
        {
            this.mobleType = mobleType;
        }
    }

 
    /// <summary>
    /// 釋出者(publiser)
    /// </summary>
    public class Publiser
    {
        //先定義委託
        public delegate void PublishEventHandler(object sender,PubEventArgs e);

        /// <summary>
        /// 定義事件,命名為委託去除EventHandler
        /// </summary>
        public event PublishEventHandler Publish;

 

        /// <summary>
        /// 執行函式
        /// </summary>
        /// <param name="e"></param>
        public void OnPublish(PubEventArgs e)
        {
            if (Publish!=null)
            {
                this.Publish(this,e);
            }
        }

        /// <summary>
        /// 事件的觸發
        /// </summary>
        /// <param name="mobleType"></param>
        public void Use( string mobleType)
        {
            OnPublish(new PubEventArgs(mobleType));
        }

    }

 
 
    /// <summary>
    /// 訂閱者(Subscriber)小明
    /// </summary>
    public class XiaoMing
    {
        public static void Receive(object sender, PubEventArgs e)
        {
            Console.WriteLine($"您的{e.mobleType}剩餘100G");
        }
    }

    public class XiaoHong
    {
        public static void Receive(object sender,PubEventArgs e)
        {
            Console.WriteLine($"您的{e.mobleType}餘額為100元");
        }
    }


    public class XiaoLi
    {
        public static void Receive(object sender, PubEventArgs e)
        {
            Console.WriteLine($"您的流量剩餘100G,您的話費餘額為100元");
        }
    }

 
    /// <summary>
    /// 小明訂閱了流量   小紅訂閱了話費  小李訂閱了話費流量。分別查詢自己所訂閱的,主流程編寫
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            //例項化一個釋出者
            Publiser publiser = new Publiser();
            Console.WriteLine("請輸入您需要查詢的業務:");
            string mobleType=Console.ReadLine();
            if (mobleType=="流量")
            {
                //事件註冊
                publiser.Publish += XiaoMing.Receive;         

            }
            else if (mobleType=="話費")
            {
                publiser.Publish += XiaoHong.Receive;
            }
            else
            {
                publiser.Publish += XiaoLi.Receive;
            }
            //呼叫觸發事件
            publiser.Use(mobleType);
        }
    }

 

  在Main函式中,進行一個事件的註冊,例如小明,進來Main函式,例項化一個釋出者,在釋出者中繫結了小明的訂閱事件,然後呼叫釋出者觸發事件的方法。

  釋出者:

    一、宣告一個委託

    二、基於委託宣告一個事件

    三、一個判斷事件是否為空,然後開始執行處理事件

    四、一個呼叫用來觸發事件的方法

  

        //先定義委託
        public delegate void PublishEventHandler(object sender,PubEventArgs e);

        /// <summary>
        /// 定義事件,命名為委託去除EventHandler
        /// </summary>
        public event PublishEventHandler Publish;    

   

         //事件註冊
         publiser.Publish += XiaoMing.Receive;    

 

  訂閱者:

    感興趣的事件,最後的輸出。

    訂閱者感興趣的物件:

    用來儲存處理訂閱者感興趣的物件。

總結

  我們仔細考慮下這整個委託與事件,事件的本質也就是對委託的一種使用。看我們事件註冊繫結和多播委託的用法是一樣的,事件的宣告也是使用的委託類。

  大家好好想想其中的奧妙,然後理解消化下。其實它們也沒有那麼難的。

  下一節我們對委託和事件進行深入解析外加實際案例。

 

                    c#基礎知識詳解系列

 

  歡迎大家掃描下方二維碼,和我一起學習更多的C#知識

 

  

相關文章