首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 委托與事件詳解(十二)

     編輯:關於C語言

前例輸出顯示多個訂閱者收到通知。但為何 .NET Framework 事件模式與之不同?為何有 EventArgs 參數?先理解 .NET 編碼規範:

  • 委托類型名以 EventHandler 結尾
  • 委托原型:void 返回值,兩個參數:Object 與 EventArgs (或其子類)
  • 事件名稱 = 委托名去掉 EventHandler
  • 繼承 EventArgs 的類型以 EventArgs 結尾

說明:

  1. Object sender 代表事件源 (Subject),如 Heater,回調可透過它訪問觸發者
  2. EventArgs 包含觀察者關心的數據,如溫度

這不只是規範,更帶來靈活性。若需在觀察端獲取熱水器型號、產地、價格,傳遞 sender 即可直接訪問,無需修改委托簽名。

重寫範例符合 .NET 規範:

using System;
namespace Delegate {
    public class Heater {
        private int temperature;
        public string type = "RealFire 001";
        public string area = "China Xian";
        public delegate void BoiledEventHandler(Object sender, BoiledEventArgs e);
        public event BoiledEventHandler Boiled;
        public class BoiledEventArgs : EventArgs {
            public readonly int temperature;
            public BoiledEventArgs(int temperature) { this.temperature = temperature; }
        }
        protected virtual void OnBoiled(BoiledEventArgs e) {
            if (Boiled != null) Boiled(this, e);
        }
        public void BoilWater() {
            for (int i = 0; i <= 100; i++) {
                temperature = i;
                if (temperature > 95) {
                    OnBoiled(new BoiledEventArgs(temperature));
                }
            }
        }
    }
    public class Alarm {
        public void MakeAlert(Object sender, Heater.BoiledEventArgs e) {
            Heater heater = (Heater)sender;
            Console.WriteLine("Alarm:{0} - {1}: ", heater.area, heater.type);
            Console.WriteLine("Alarm: 嘀嘀嘀,水已經 {0} 度了:", e.temperature);
        }
    }
    public class Display {
        public static void ShowMsg(Object sender, Heater.BoiledEventArgs e) {
            Heater heater = (Heater)sender;
            Console.WriteLine("Display:{0} - {1}: ", heater.area, heater.type);
            Console.WriteLine("Display:水快燒開了,當前溫度:{0}度。", e.temperature);
        }
    }
    class Program {
        static void Main() {
            Heater heater = new Heater();
            Alarm alarm = new Alarm();
            heater.Boiled += alarm.MakeAlert;
            heater.Boiled += (new Alarm()).MakeAlert;
            heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlert);
            heater.Boiled += Display.ShowMsg;
            heater.BoilWater();
        }
    }
}

輸出顯示多個訂閱者(含匿名對象與靜態方法)均正確接收事件。總結:本系列從委托概念切入,引出事件,講解中間代碼,再以熱水器範例實作 Observer 模式,闡述 .NET 委托事件實現方式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved