首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C#委托核心概念與事件模式:從匿名方法到Lambda表達式的進階之路

     編輯:程式設計綜合問答

委托本質

委托是類型安全的函數指針,封裝了「方法簽名」(參數列表、返回類型)。它是**引用類型**,可以像對象一樣傳遞、存儲、組合。

你已經在用委托了

// WinForms / WPF 事件綁定本質
button.Click += Button_Click; // Button_Click 方法被封裝為 EventHandler 委托實例

// 等價於
button.Click += new EventHandler(Button_Click);

// EventHandler 定義
public delegate void EventHandler(object sender, EventArgs e);

委托演進史

核心類型:Func / Action / Predicate


// 無返回值,0-16參數
Action act = () => Console.WriteLine("Hi");
Action act2 = (i, s) => Console.WriteLine($"{i}: {s}");

// 有返回值,最後一個類型為返回類型
Func add = (a, b) => a + b;
Func getTime = () => DateTime.Now.ToString();

// 返回 bool,常用於篩選
Predicate isLong = s => s.Length > 10;

多播委托

Action multi = null;
multi += () => Console.WriteLine("First");
multi += () => Console.WriteLine("Second");
multi(); // 依次調用,輸出 First 後 Second

// 移除
multi -= () => Console.WriteLine("First"); // 注意:需保持同一委托實例引用才能移除

進階:事件模式標準實現

public class Timer {
    // 1. 定義委托類型(或直接用 EventHandler)
    public event EventHandler Elapsed;

    // 2. 觸發方法(線程安全模式)
    protected virtual void OnElapsed(ElapsedEventArgs e) {
        Volatile.Read(ref Elapsed)?.Invoke(this, e);
    }

    // 3. 內部邏輯觸發
    private void Loop() {
        while (running) {
            Thread.Sleep(interval);
            OnElapsed(new ElapsedEventArgs(DateTime.Now));
        }
    }
}

// 訂閱者
timer.Elapsed += (sender, e) => Console.WriteLine($"Tick at {e.Time}");

學習路徑建議

  1. 掌握 `Func/Action/Predicate` 常用簽名,減少自定義委托
  2. 理解**閉包捕獲變量生命週期**(`foreach` 陷阱、異步委托)
  3. 學習 `async/await` 與委托結合(`Task.Run(() => ...)`)
  4. 閱讀 .NET Core 源碼中委托實現(`MulticastDelegate`)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
版本語法示例特點
C# 1.0命名方法`del = new Del(MethodName);`需單獨定義方法
C# 2.0匿名方法`del = delegate(int x) { return x*2; };`內聯代碼、捕獲外部變量
C# 3.0Lambda 表達式`del = x => x * 2;`簡潔、類型推斷、表達式樹
C# 7.0+局部函數`int Local(int x) => x*2; del = Local;`僅當前方法可見、避免委托分配