第十四章 事件

14.1 發(fā)布者/訂閱者

  • 發(fā)布者(publisher):發(fā)布某個事件的類或結(jié)構(gòu),其他類可以在該事件發(fā)生時得到通知。
  • 訂閱者(subscriber):注冊并在事件發(fā)生時得到通知的類或結(jié)構(gòu)
  • 事件處理程序(event handler) :由訂閱者注冊到事件的方法,在發(fā)布者觸發(fā)事件時執(zhí)行。事件處理程序方法可以定義在事件所在的類或結(jié)構(gòu)中,也可以定義在不同的類或結(jié)構(gòu)中。
  • 觸發(fā)(raise)事件 調(diào)用(invoke)或觸發(fā)(fire)事件的術(shù)語:當事件觸發(fā)時,所有注冊到它的方法都會被依次調(diào)用。

有關(guān)事件的私有委托

  • 事件提供了對它的私有控制委托的結(jié)構(gòu)化訪問。即你無法直接訪問委托。
  • 事件中可用的操作比委托少,對于事件我們只可以添加、刪除或調(diào)用事件處理程序。
  • 事件被觸發(fā)時,它調(diào)用委托來依次調(diào)用調(diào)用列表中的方法。

14.2 源代碼組件概覽

一個完整的組件由5部分組成:

  • 委托類型聲明:事件和事件處理程序必須有共同的簽名和返回類型,他們通過委托類型進行描述。
  • 事件處理程序聲明:訂閱者類中會在事件觸發(fā)時執(zhí)行的方法聲明??梢允秋@式命名的方法,也可以是匿名方法或Lambda表達式。
  • 事件聲明:發(fā)布者類必須聲明一個訂閱者類可以注冊的事件成員。當聲明的事件為public時,稱為發(fā)布了事件。
  • 事件注冊:訂閱者必須訂閱事件才能在它被觸發(fā)時得到通知。
  • 觸發(fā)事件的代碼:發(fā)布者類中“觸發(fā)”事件并導(dǎo)致調(diào)用注冊的所有事件處理程序的代碼。
    使用事件時的5個源代碼組件
static class Program
    {
        static void Main()
        {
            Incrementer incrementer = new Incrementer();
            Dozens dozensCounter = new Dozens(incrementer);
            incrementer.DoCount();
            Console.WriteLine("Number of dozens = {0}", dozensCounter.DozensCount);
            Console.ReadKey();
        }
//發(fā)布者類
        class Incrementer
        {
            public delegate void Handler();//委托類型聲明
            public event Handler CountADozen;//事件聲明

            public void DoCount()
            {
                for (int i = 1; i < 100; i++)
                {
                    if (i % 12 == 0 && CountADozen != null)
                    {
                        CountADozen();//觸發(fā)事件代碼
                    }
                }
            }
        }
//訂閱者類
        class Dozens
        {
            public int DozensCount { get; private set; }

            public Dozens(Incrementer incrementer)
            {
                DozensCount = 0;
                incrementer.CountADozen += IncrementerDozensCount;//事件注冊
            }

            void IncrementerDozensCount()//事件處理程序聲明
            {
                DozensCount++;
            }
        }
    }

14.6 標準事件的用法

程序事件的異步處理是使用C#事件的絕佳場景。WindowsGUI編程廣泛地使用了事件,.NET框架提供了一個標準模式。事件使用的標準模式的根本是System命名空間聲明的EventHandler委托類型。
public delegate void EventHandler(object sender, EventArgs e);

  • 第一個參數(shù)用來保存觸發(fā)事件的對象的引用。由于是object類型,可以匹配任何類型的實例。
  • 第二個參數(shù)用來保存狀態(tài)信息,指明什么類型適用于該應(yīng)用程序;
  • 返回類型是 void
  • EventArgs設(shè)計為不能傳遞任何數(shù)據(jù)。它用于不需要傳遞數(shù)據(jù)的事件處理程序——通常會被忽略。
  • 如果要傳遞數(shù)據(jù),必須聲明一個派生自EventArgs的類,使用合適的字段來保存需要傳遞的數(shù)據(jù)。

修改上述程序使之使用標準EventHandler委托:

static class Program
    {
        static void Main()
        {
            Incrementer incrementer = new Incrementer();
            Dozens dozensCounter = new Dozens(incrementer);
            incrementer.DoCount();
            Console.WriteLine("Number of dozens = {0}", dozensCounter.DozensCount);
            Console.ReadKey();
        }

        class Incrementer
        {
            public event EventHandler CountADozen;//使用系統(tǒng)定義的EventHandler委托

            public void DoCount()
            {
                for (int i = 1; i < 100; i++)
                {
                    if (i % 12 == 0 && CountADozen != null)
                    {
                        CountADozen(this, null);//觸發(fā)事件時使用EventHandler的參數(shù)
                    }
                }
            }
        }

        class Dozens
        {
            public int DozensCount { get; private set; }

            public Dozens(Incrementer incrementer)
            {
                DozensCount = 0;
                incrementer.CountADozen += IncrementerDozensCount;
            }

            void IncrementerDozensCount(object sender, EventArgs e)//事件處理程序的簽名必須與委托的簽名匹配
            {
                DozensCount++;
            }
        }
    }
14.6.1 通過擴展EventArgs來傳遞參數(shù)

要向事件處理程序的第二個參數(shù)傳入數(shù)據(jù),需要聲明一個派生自EventArgs的自定義類,可以保存要傳的數(shù)據(jù)。

static class Program
    {
        static void Main()
        {
            Incrementer incrementer = new Incrementer();
            Dozens dozensCounter = new Dozens(incrementer);

            incrementer.DoCount();
            Console.WriteLine("Number of dozens = {0}", dozensCounter.DozensCount);
            Console.ReadKey();
        }

        public class IncrementerEventArgs : EventArgs//自定義類派生自EventArgs
        {
            public int IterationCount { get; set; }//存儲一個整數(shù)
        }

        class Incrementer
        {
            public event EventHandler<IncrementerEventArgs> CountADozen;//使用、自定義類的泛型委托

            public void DoCount()
            {
                IncrementerEventArgs args = new IncrementerEventArgs();//自定義類對象
                for (int i = 1; i < 100; i++)
                {
                    if (i % 12 == 0 && CountADozen != null)
                    {
                        CountADozen(this, args);//觸發(fā)事件時傳遞參數(shù)
                    }
                }
            }
        }

        class Dozens
        {
            public int DozensCount { get; private set; }

            public Dozens(Incrementer incrementer)
            {
                DozensCount = 0;
                incrementer.CountADozen += IncrementerDozensCount;
            }

            void IncrementerDozensCount(object sender, IncrementerEventArgs e)//事件處理程序的簽名必須與委托的簽名匹配
            {
                Console.WriteLine("Incremented at iteration: {0} in {1}", e.IterationCount, sender.ToString());

                DozensCount++;
            }
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • #1. 委托1.1 聲明委托1.2 使用委托1.3 簡單委托示例1.4 Action<T>和Func<T>委托1....
    MrDecoder閱讀 737評論 0 2
  • 一、理解事件事件采用發(fā)布/訂閱模型,其中發(fā)行者決定在什么情況下引發(fā)事件,而訂戶決定為響應(yīng)事件而執(zhí)行的操作。事件可以...
    CarlDonitz閱讀 343評論 0 0
  • 網(wǎng)上講C#委托和事件的博文已經(jīng)非常多了,其中也不乏一些深入淺出、條理清晰的文章。我之所以還是繼續(xù)寫,主要是借機整理...
    丑小丫大笨蛋閱讀 1,189評論 0 5
  • 定義:委托是一種引用類型,表示對具有特定參數(shù)列表和返回類型的方法的引用。 在實例化委托時,你可以將其實例與任何具有...
    52718閱讀 7,740評論 3 14
  • 事件 事件含義 事件由對象引發(fā),通過我們提供的代碼來處理。一個事件我們必須訂閱(Subscribe)他們,訂閱一個...
    天堂邁舞閱讀 3,144評論 1 7

友情鏈接更多精彩內(nèi)容