快速理解C#高級概念(二) 事件與委托的區別


根據上篇博文的反響我想向大家說明,因為本人時間有限加上才疏學淺,無法寫出面面俱到的博文。我只是把自己經歷的覺得有些意義的技術點分享出來,希望大家見諒。當然,我不會讓大家走上歧途的。所有示例都是親測。

今天我想討論一下事件與委托之間的聯系。很多人說,事件即委托。真的是這樣嗎?那么微軟為何又要定義事件與委托兩個概念呢?
其實事件即委托,在我看來不如這樣解釋:事件是封裝過的委托實例。也就是說,事件是面向對象的產物,它是封裝性比較典型的示例。

首先我們來看一下事件的定義以及調用:

 

    //定義委托
    public delegate int MathHandle(int a, int b);
    public class Test
    {
        //定義事件
        public event MathHandle MathEvent;
        public int Add(int a, int b)
        {
            return a + b;
        }
        public void Operation(int a, int b)
        {
            Console.WriteLine(this.MathEvent(a, b));
        }
    }
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            Test t = new Test();
            //為事件方法隊列添加方法
            t.MathEvent += new MathHandle(t.Add);
            t.Operation(1,2);//此處如果調用t.MathEvent(1,2)會編譯錯誤;
        }
    }

執行結果:

我們再看看,如果我們將使用委托來實現上述方法:

    //定義委托
    public delegate int MathHandle(int a, int b);
    public class Test
    {
        public MathHandle MathEvent;
        public int Add(int a, int b)
        {
            return a + b;
        }
    }
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            Test t = new Test();
            //為委托隊列添加方法
            t.MathEvent += new MathHandle(t.Add);
            Console.WriteLine(t.MathEvent(1, 2));//委托可以直接在實例外部執行。
        }
    }

執行結果:

從上面示例我們看到,同一個方法你可以使用委托來調用,你也可以使用事件來調用。那究竟有何不同?
其實事件就是一個狹義的委托,也就是事件是一個用於事件驅動模型的專用委托.你可以在客戶代碼中直接調用委托來激發委托指向的函數,而事件不可以,事件的觸發只能由服務代碼自己觸發。也就是說在你的代碼里委托你不但可以安排誰是它的調用函數,還可以直接調用它,而事件不能直接調用,只能通過某些操作觸發。除此之此,事件擁有委托的所有功能,包括多播特性。即事件可以有多個事件處理函數,委托同樣也可以是個多播委托.

希望能從這個小小的示例,向大家傳達到事件與委托的區別。
下面再貼一個稍微復雜的示例:

    public class Heater 
    {
        private int temperature;
        public void BoilWater() 
        {
            for (int i = 1; i <= 100; i++) 
            {
                temperature = i;
                if (temperature > 95 && BoilEvent != null) 
                {
                    //執行委托,無需知道要執行哪些方法
                    BoilEvent(temperature);
                }
            }
        }
        public delegate void BoilHandle(int param);
        public event BoilHandle BoilEvent;//封裝了委托
    }
    public class Alarm 
    {
        public void MakeAlert(int param) 
        {
            Console.WriteLine("Alarm:水溫已經超過{0}度.",param);
        }
    }
    public class Display
    {
        public void ShowMsg(int param)
        {
            Console.WriteLine("Display:水已燒開,當前溫度{0}度.", param);
        }
    }
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            Heater heater = new Heater();
            Alarm alarm = new Alarm();
            heater.BoilEvent += alarm.MakeAlert;
            heater.BoilEvent += new Display().ShowMsg;
            heater.BoilWater();
        }
    }

 

更多WEB開發技術請加群:Asp.Net高級群 號碼:261882616  博主以及同事和你共同探討感興趣的話題。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM