1. 程式人生 > >從釋出者和訂閱者來看事件

從釋出者和訂閱者來看事件

寫一個事件程式碼,只需要記住5個部分即可,如圖所示:


1.宣告委託:事件和事件處理程式必須有共同的簽名和返回型別,它們通過委託型別進行描述。

2.宣告事件:釋出者類必須宣告一個訂閱者類可以註冊的事件成員。

3.觸發事件:釋出者類中觸發事件,便會呼叫註冊在事件上的所有事件處理程式。

4.註冊事件:訂閱者必須訂閱事件才能在事件被觸發時得到通知。

5.處理事件:訂閱者會在事件發生後執行相應的處理程式。


一、貓和老鼠的例子(不傳遞資料)

程式碼如下:

using System;
namespace 練習專用
{
    //宣告委託
    public delegate void MyDel();

    //釋出者類-貓
    class Cat
    {
        //宣告事件
        public event MyDel CatCryEvent;
        //在貓叫的方法中觸發事件
        public void Cry()
        {
            Console.WriteLine("有隻貓在叫。。。");
            //觸發事件
            CatCryEvent();
        }
    }

    //訂閱者類-老鼠
    class Mouse
    {
        public Mouse(Cat cat)
        {
            //註冊事件,訂閱者老鼠向事件新增事件處理程式
            cat.CatCryEvent += Run;
        }
        //處理事件,事件發生後的處理程式
        void Run()
        {
            Console.WriteLine("老鼠快跑吧!!!");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Cat cat1 = new Cat();
            Mouse mouse1 = new Mouse(cat1);
            cat1.Cry();
        }
    }
}


二、貓和老鼠的例子(傳遞資料)

可以使用System名稱空間提供的EventHandler委託型別,所以不需要自己定義委託型別了,它是這麼定義的:

public delegate void EventHandler(object sender, EventArgs e);
//第一個引數用來儲存觸發事件的物件的引用。由於是object類,所以可以匹配任何型別的例項
//第二個引數用來儲存狀態資訊,指明什麼型別適用於該應用程式
為了向事件處理程式的第二個引數傳入資料,需要宣告一個派生自EventArgs的自定義類來儲存需要傳入的資料。

程式碼如下:

using System;
namespace 練習專用
{
    //自定義一個派生自EventArgs的類,儲存資料
    class CryEventArgs : EventArgs
    {
        //儲存一個字串
        public string CatName
        {
            get;
            set;
        }
    }

    //釋出者類-貓
    class Cat
    {
        public string CatName
        {
            get;
            set;
        }
        //建構函式,給貓弄個名字
        public Cat(string name)
        {
            this.CatName = name;
        }
        //宣告事件,使用自定義類的泛型委託
        public static event EventHandler<CryEventArgs> CatCryEvent;
        //在貓叫的方法中觸發事件
        public void Cry()
        {
            Console.WriteLine("有隻貓在叫。。。");
            //把貓的名字儲存到剛才的自定義類中
            CryEventArgs e = new CryEventArgs();
            e.CatName = this.CatName;
            //觸發事件,傳遞引數
            CatCryEvent(this, e);
        }
    }

    //訂閱者類-老鼠
    class Mouse
    {
        public Mouse()
        {
            //註冊事件,訂閱者老鼠向事件新增事件處理程式
            Cat.CatCryEvent += Run;
        }
        //處理事件,事件發生後的處理程式
        void Run(object sender, CryEventArgs e)
        {
            if (e.CatName == "黑貓警長")
            {
                Console.WriteLine("是黑貓警長,老鼠快特麼的跑吧!!!");
            }
            else
            {
                Console.WriteLine("不是黑貓警長,是{0},老鼠不用跑了。。。", e.CatName);
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Cat cat1 = new Cat("黑貓警長");
            Cat cat2 = new Cat("小貓咪");
            Mouse mouse = new Mouse();
            cat1.Cry();
            Console.WriteLine("===============手動分割線===============");
            cat2.Cry();
        }
    }
}