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

C# 委派與事件完整指南:從委派基礎到事件模式實作

     編輯:關於C語言

委派

委派是型別安全的物件導向函數指標,可參考靜態/實例方法。三步驟:宣告、實例化、呼叫。

宣告與使用

// 1. 宣告委派型別
public delegate void MyDelegate(string name);

// 2. 目標方法
public static void MyDelegateFunc(string name)
{
    Console.WriteLine($"Hello, {name}");
}

// 3. 實例化並呼叫
public static void Main()
{
    MyDelegate md = new MyDelegate(MyDelegateFunc); // 或簡寫 MyDelegate md = MyDelegateFunc;
    md("sam1111"); // 呼叫委派
}

委派特性

  • 可參考實例方法(自動捕獲 this)。
  • 型別安全:編譯期檢查簽章相容。
  • 受控物件:執行期保證指向有效方法。
  • 支援多播:+/+= 組合,-/-= 移除,依序呼叫。

多播委派範例

delegate void MyDelegate(string s);

static void Hello(string s) => Console.WriteLine($"Hello, {s}!");
static void Goodbye(string s) => Console.WriteLine($"Goodbye, {s}!");

static void Main()
{
    MyDelegate a = Hello, b = Goodbye;
    MyDelegate c = a + b;  // 組合
    MyDelegate d = c - a;  // 移除 a

    a("A"); // Hello, A!
    b("B"); // Goodbye, B!
    c("C"); // Hello, C! -> Goodbye, C!
    d("D"); // Goodbye, D!
}

事件

事件是基於委派的發佈-訂閱機制,限制外部只能 +=/-=,不能直接呼叫或覆寫。

標準事件模式實作步驟

  1. 定義委派:public delegate void MyEventHandler(object sender, MyEventArgs e);
  2. 定義事件參數類別(繼承 EventArgs),無參數可直接用 EventArgs。
  3. 定義事件處理方法(簽章符合委派)。
  4. 用 event 關鍵字宣告事件成員。
  5. += 訂閱,-= 取消訂閱。
  6. 撰寫 protected virtual void OnEventName(EventArgs e) 觸發方法(檢查 null)。
  7. 在適當處呼叫 OnEventName 引發事件。

完整範例

using System;

public class EventTest
{
    // 1. 委派
    public delegate void MyEventHandler(object sender, EventArgs e);

    // 2. 事件參數類別(此處無額外資料,直接用 EventArgs)

    // 3. 事件處理方法
    public class MyEventCls
    {
        public void MyEventFunc(object sender, EventArgs e)
        {
            Console.WriteLine("My event is ok!");
        }
    }

    // 4. 事件宣告
    private event MyEventHandler myEvent;
    private readonly MyEventCls myEcls = new MyEventCls();

    public EventTest()
    {
        // 5. 訂閱
        myEvent += new MyEventHandler(myEcls.MyEventFunc);
    }

    // 6. 觸發方法
    protected virtual void OnMyEvent(EventArgs e)
    {
        myEvent?.Invoke(this, e); // C# 6.0+ null 條件運算子
    }

    // 7. 對外引發
    public void RaiseEvent()
    {
        OnMyEvent(EventArgs.Empty);
    }

    public static void Main()
    {
        var et = new EventTest();
        Console.Write("Please input 'a': ");
        string s = Console.ReadLine();
        if (s == "a") et.RaiseEvent();
        else Console.WriteLine("Error");
    }
}

關鍵差異總結

特性委派事件
關鍵字delegateevent
外部可直接呼叫是否(僅能 +=/-=)
外部可直接指派 (=)是否
用途回呼、策略、多播通知、解耦、發佈-訂閱

現代 C# 建議

  • 優先使用 EventHandler<TEventArgs> 泛型委派,避免自訂委派型別。
  • 事件觸發用 ?.Invoke() 簡化 null 檢查。
  • 考慮 record 型別作為事件參數(不可變、語意清晰)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved