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

C# 事件模式入門:委派、事件宣告與觸發完整範例

     編輯:關於C語言

核心程式碼解析


// 1. 定義委派型別 (事件簽名)
public delegate void ActionEventHandler(object sender, EventArgs e);

// 2. 宣告事件 (基於委派)
public static ActionEventHandler Action;

// 3. 觸發事件的保護方法 (慣例命名 On + 事件名)
protected void OnAction(object sender, EventArgs e)
{
    if (Action != null)  // 防止無訂閱者時拋出 NullReferenceException
    {
        Action(sender, e);
    }
}

// 4. 事件處理方法 (符合委派簽名)
public void MyHandler(object sender, EventArgs e)
{
    // 處理邏輯...
}

// 5. 訂閱事件 (通常在 Form_Load 或建構函式中)
private void Form1_Load(object sender, EventArgs e)
{
    Action += new ActionEventHandler(MyHandler);  // 訂閱
    OnAction(sender, e);                          // 觸發測試
}

關鍵概念圖解

元素角色關鍵字
委派定義事件簽名 (參數/回傳型別)delegate
事件發佈者暴露的通知點event
訂閱將處理方法加入事件調用清單+=
取消訂閱從調用清單移除處理方法-=
觸發呼叫事件,依序執行所有訂閱者Invoke()

標準事件模式 (Microsoft 設計指南)


public class MyClass
{
    // 1. 事件引數類別 (攜帶資料)
    public class MyEventArgs : EventArgs
    {
        public string Message { get; set; }
        public int Code { get; set; }
    }

    // 2. 事件委派 (慣例: EventHandler 結尾)
    public event EventHandler MyEvent;

    // 3. 觸發方法 (慣例: On + 事件名, protected virtual)
    protected virtual void OnMyEvent(MyEventArgs e)
    {
        MyEvent?.Invoke(this, e);  // C# 6.0 null 條件運算子
    }

    // 4. 公開方法觸發事件
    public void DoSomething()
    {
        OnMyEvent(new MyEventArgs { Message = "完成", Code = 200 });
    }
}

// 使用端
var obj = new MyClass();
obj.MyEvent += (sender, e) => Console.WriteLine($"{e.Message}: {e.Code}");
obj.DoSomething();

進階主題

  • 事件存取器:自訂 add/remove 邏輯 (如弱引用事件、執行緒安全)
  • 介面事件:介面中宣告事件,實作類別需提供事件
  • 靜態事件:全域通知機制,注意記憶體洩漏 (需明確取消訂閱)
  • 非同步事件:使用 Task 或 BeginInvoke 非同步觸發

常見錯誤與最佳實務

錯誤正確做法
直接呼叫事件 (Action())透過 OnAction() 觸發,支援 null 檢查與衍生類別覆寫
忘記 null 檢查使用 Action?.Invoke() (C# 6+) 或 if (Action != null)
事件處理方法拋出例外中斷後續訂閱者每個訂閱者包裝 try-catch,或使用 GetInvocationList() 手動逐個調用
未取消訂閱導致記憶體洩漏在 Dispose/Unload 時執行 Action -= Handler
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved