事件與委託

來源:互聯網
上載者:User

   網上有好多講委託與事件的文章,寫得都很不錯,以下是我對事件與委託的理解,若有不當之處,請提出,萬分感謝。

   為了方便閱讀,我將代碼寫在了後面,前面介紹了一些跟代碼有關的資訊。

  Observe模式中,主體subject指受監控者,觀察者observer指監控者。記憶體狀態(MemeryStatus)是受監控者,屬於主體;Observer是監控者,屬於觀察者;
  主體中往往有一個或多個觀察者感興趣的資訊,此例中式currentVolume,即當前記憶體容量,主體中還應該有定義好的事件,主體中的事件在用戶端(一般指含有Main函數的類)與觀察者中的處理方法綁定,當主體滿足某一條件時(此例中指滿足currentVolume>95時),就應該激發事件(此例中指MemeryObserve(this, args);),之後,與該事件綁定的所有觀察者端的處理方法都會執行(這叫回調),這樣,通過事件,將主體端的狀態變化和觀察者端的監控相關聯,主體變化,觀察者就能做出相應變化了。
      換種方式看本常式序,其實很熟悉,開啟VS建立一個C# Winform應用程式,在預設表單中拖放一個button控制項,雙擊該控制項,在Form1.cs中將會自動產生單擊處理常式
        private void button1_Click(object sender, EventArgs e)
        {

        }
仔細一看,該處理方法跟本例Observer類中的  public void Warning(object sender, MemeryObserveEventArgs args)很相似最後一個參數稍微有些差別,這是因為各自訂的事件參數不同, 在void Warning(object sender, MemeryObserveEventArgs args)中,我們要獲得subject(主體)的當前容量,即currentVolume,而在void button1_Click(object sender, EventArgs e)中,我們可能 要擷取其他與subject有關的資訊,開啟Form1.Designer.cs檔案,展開"Windows 表單設計器產生的程式碼"你會找到"this.button1.Click += new System.EventHandler(this.button1_Click)"這句代碼,再仔細一看,你會發現它跟本例寫過的 status.MemeryObserve+=new MemeryObserveEventHandler(observer.Warning);這句很相似。我們知道,MemeryObserveEventHandler是我們定義的一個委託,它的方法簽名要求這樣的形式"void 函數名(object param1,MemeryObserveEventArgs param2)",那麼,System.EventeHandler其實也是個委託,類似這樣定義:public delegate void EventHandler(object sender,EventArgs args).所以,button類就是Observer模式中的主體,相當於本例 中的MemeryStatus類 ,this.button1相當於本例中的status(事件發行者),Form1(即表單類)就相當於本例中的observer(觀察者)。這樣,觀察者(Form1)觀察被觀察者(Button)的狀態變化(比如被單擊),作出相應的動作(執行void Warning(object sender, MemeryObserveEventArgs args))。

我們現在來比較一下本常式序和建立winform預設程式

1、本例中主體(即事件發行者)為MemeryStatus類,winform中的主體為Button類;

2、本例中事件為MemeryObserve,winform中事件為Click;

3、本例中事件參數類為MemeryObserveEventArgs,winform中事件參數類為EventArgs;

4、本例中觀察者(即事件訂閱者)為Observer類,winform中觀察者為表單,即Form1類;

5、本例中當事件發生,回呼函數為 public void Warning(object sender, MemeryObserveEventArgs args) ,winform中回呼函數為private void    button1_Click(object sender, EventArgs e);
6、本例中當記憶體已用容量大於95時,觸發事件MemeryObserve,winform中當使用者點擊按鈕時,觸發事件Click;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class MemeryObserveEventArgs : EventArgs    //事件參數類
    {
        private readonly int currentVolume;
        public int CurrentVolume
        {
            get
            {
                return currentVolume;
            }
        }
        public MemeryObserveEventArgs(int C)
        {
            this.currentVolume = C;
        }
    }

    public delegate void MemeryObserveEventHandler(object sender,MemeryObserveEventArgs args);  //委託

    public class MemeryStatus                        //subject,主體/publisher,事件發行者
    {
        private int currentVolume;
        public event MemeryObserveEventHandler MemeryObserve;   //定義待激發事件

        public int CurrentVolume
        {
            get
            {
                return currentVolume;
            }
            set
            {
                if (value > 95)                          //給執行個體currentVolume賦值,如果當前已用容量大於95,則激發事件MemeryObserve
                {
                    currentVolume = value;

                    if (MemeryObserve != null)            //如果事件有方法綁定
                    {
                        MemeryObserveEventArgs args=new MemeryObserveEventArgs(value);  //構建事件參數
                        MemeryObserve(this, args);           //激發事件
                    }
                }
            }
        }

    }

    public class Observer                               //觀察者,observer/事件訂閱者
    {
        public void Warning(object sender, MemeryObserveEventArgs args)  //observer方的處理方法,應和前面聲明的委託有同樣的方法簽名
        {
            Console.Write("當前容量超過上限容量{0}\n", args.CurrentVolume);
        }
    }

    class Program                                        //用戶端
    {
        static void Main(string[] args)
        {
            MemeryStatus status = new MemeryStatus(); //建立subject執行個體
            Observer observer = new Observer();   //建立observer執行個體

            status.MemeryObserve+=new MemeryObserveEventHandler(observer.Warning);  //將observer方的處理方法(observer.Warning)綁定到subject方(status.MemeryObserve)事件

            for (int i = 1; i < 100; i++)
            {
                status.CurrentVolume = i;   //以此增加subject方的當前容量,當滿足一定條件時,會激發subject方的事件
            }
            Console.Read();
        }
    }
}

//輸出結果:
//當前容量超過上限容量96
//當前容量超過上限容量97
//當前容量超過上限容量98
//當前容量超過上限容量99
//本代碼在VS2008中運行通過

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.