C#委託和事件

委託是一種定義方法的類,這樣就可使得方法A,能夠像string類、int類同樣當作方法B的參數進行傳遞。這種將方法動態地賦值給參數的作法,能夠避免在代碼中大量使用if-else(or switch)語句,同時使得程序具備更好的可擴展性。委託被大量使用在WPF中(至少我是這麼認爲的)。可是委託類不一樣於string類和int類的區別在於,能夠將多個方法賦給同一個委託,或者說多個方法能夠綁定到同一個委託類上,當調用該委託時,將依次調用其所綁定的方法,可是string類和int類,後面綁定的參數將會替換掉前一個參數。html

事件用於封裝委託類。當使用string類時,能夠經過屬性對字段進行封裝,某個string類能夠只讀的,也能夠是隻寫的。使用event關鍵字,聲明一個事件也就是聲明瞭一個進行了封裝的委託類型變量,好比下面這條代碼:git

public event PropertyChangedEventHandler PropertyChanged;

其中,PropertyChangedEventHandler是一個委託類,event關鍵字定義了一個封裝該委託的PropertyChanged事件。事件封裝了委託,那麼就能夠將方法註冊到事件中,當事件發生時,會依次調用註冊了該事件的方法。好比在WPF中,給一個button控件添加Click方法,其實就是將Btn_Click方法註冊到button控件的Click事件中,即button.Click += Btn_Click.github

.NET Framework中對委託和事件編寫的規範:學習

  • 委託類型的名稱都應該以EventHandler結尾;
  • 委託的返回值是void(最好),並接受兩個輸入參數,一個是Object類,一個EventArgs類(或繼承自EventArgs);
  • 事件的命名爲委託去掉EventHandler以後剩餘的部分;
  • 繼承自EventArgs的類型應該以EventArgs結尾;
  • 訂閱事件的方法命名,一般爲On+事件名。

Example:這個例子來源於張子陽博客中的例子,我最開始學習委託和事件也是看了這篇博客,因此個人這篇文章算是學習了委託和事件以後的一個整理,目的是加深本身的記憶。張子陽的博客地址以下:this

http://www.tracefact.net/tech/009.htmlspa

http://www.tracefact.net/tech/029.html.net

例子是這樣的,假設有一臺熱水器,當加熱到指定溫度時會提醒用戶,則有一個加熱方法,還有一個提醒方法。提醒方法要註冊加熱事件,當溫度達到指定值時,調用提醒方法。code

Heater類htm

public class Heater
    {
        private int temperature;
        // 定義一個名爲BoiledEventHandler的委託類,兩個參數,一個object類,一個是繼承自EventArgs類的BoiledEventArgs類
        public delegate void BoiledEventHandler(object sender, BoiledEventArgs e);
        // 定義一個封裝BoiledEventHandler委託的事件
        public event BoiledEventHandler Boiled;

        // 訂閱Boiled事件的方法
        protected virtual void OnBoiled(BoiledEventArgs e)
        {
            // 若是有方法註冊了該事件,則調用全部註冊了該事件的方法
            if (Boiled != null)
                Boiled(this, e);
        }

        // Heater類中有一個加熱的方法
        public void BoilWater()
        {
            for (int i = 0; i <= 100; i++)
            {
                temperature = i;
                if (i % 10 == 0 && i <=95)
                    Console.WriteLine("Temperature is {0}.", i);
                if(temperature > 95)
                {
                    BoiledEventArgs e = new BoiledEventArgs(temperature);
                    OnBoiled(e);
                }
            }
        }
    }

Alarm類blog

public class Alarm
    {
        public void MakeAlert(object sender, BoiledEventArgs e)
        {
            Heater heater = sender as Heater;
            Console.WriteLine("Alarm : Temperature is {0}.", e.temperature);
        }
    }

客戶端程序

class Program
    {
        static void Main(string[] args)
        {
            Heater heater = new Heater();
            Alarm alarm = new Alarm();

            // 將Alarm中的MakeAlert方法註冊到Heater的Boiled事件中
            heater.Boiled += alarm.MakeAlert;

            heater.BoilWater();

            Console.Read();
        }
    }

 源代碼github地址:

https://github.com/Larissa1990/DelegateExample

相關文章
相關標籤/搜索