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

C# 2.0 委派與匿名委派進階應用

     編輯:關於C#

委派是 C# 型別安全的函式指標,支援多點廣播、實例/靜態方法綁定。C# 2.0 引入匿名委派進一步簡化語法,並透過閉包機制捕獲外部變數,極大增強表達能力。本文對比傳統與匿名委派語法,並展示非同步呼叫、上下文捕獲等進階應用場景。

委派基礎回顧

C# 1.x 傳統寫法:

public delegate void TheEvent(int a);
public void Test()
{
    TheEvent testdel1 = new TheEvent(Del1); // 顯式建構
    testdel1(12);
}
public void Del1(int x) { Console.WriteLine("output x: {0}", x); }

C# 2.0 簡化語法(方法群組轉換):

TheEvent testdel1 = Del1; // 隱式轉換
testdel1(12);

匿名委派語法與優勢

delegate void TheEvent2(int a);
public void Test2()
{
    int a = 12;
    TheEvent2 ev2 = delegate(int x) { Console.WriteLine("output x: {0}", x); };
    ev2(a);
}

更強大之處在於捕獲外部區域變數:

public static void Test3()
{
    int a = 12;
    int y = 32; // 外部區域變數
    TheEvent ev2 = delegate(ref int x) 
    { 
        Console.WriteLine("output x + y: {0}", x + y); // 直接存取 y
    };
    ev2(ref a); // 輸出 44
}

傳統委派無法存取參數以外的區域變數,匿名委派透過閉包機制打破此限制。

非同步呼叫與上下文捕獲

結合 BeginInvoke/EndInvoke 實作非同步模式,匿名委派自動捕獲呼叫端上下文:

public static void Test4()
{
    int a = 12;
    int y = 32;
    TheEvent ev2 = delegate(ref int x)
    {
        Console.WriteLine("output x + y: {0}", x + y);
        Thread.Sleep(100); // 模擬耗時運算
    };

    // 非同步啟動
    IAsyncResult ar = ev2.BeginInvoke(ref a, 
        delegate(IAsyncResult ar2) // 完成回呼也是匿名委派
        {
            Console.WriteLine("完成: 執行緒 {0}, 集區執行緒 {1}", 
                Thread.CurrentThread.GetHashCode(), Thread.CurrentThread.IsThreadPoolThread);
        }, 
        null);

    Console.WriteLine("主執行緒繼續執行其他運算...");
    Console.WriteLine("狀態: {0}, 主執行緒 {1}, 集區 {2}", 
        ar.IsCompleted, Thread.CurrentThread.GetHashCode(), Thread.CurrentThread.IsThreadPoolThread);
    
    Thread.Sleep(500); // 等待完成
    ev2.EndInvoke(ref a, ar);
}

輸出顯示工作項目被排入執行緒集區執行,主執行緒可繼續處理其他邏輯。匿名委派完整複製當時可用的區域變數(a、y),使回呼邏輯自然存取上下文資料。

注意事項與最佳實務

  • 變數捕獲生命週期:被捕獲變數生命週期延伸至委派存活期間,可能導致非預期行為(參見匿名方法迴圈陷阱)。
  • 執行緒安全:多執行緒存取共享捕獲變數需自行同步。
  • 可讀性權衡:大型匿名委派降低可讀性,複雜邏輯建議改用具名方法。
  • 序列化限制:匿名委派產生的閉包類別不可序列化,不適用於跨應用程式域/遠端呼叫場景。

總結

C# 2.0 匿名委派不僅是語法糖,其閉包特性實現了區域變數捕獲,配合非同步模式可編寫極具表達力的並行程式碼。理解其編譯器實作(巢狀類別閉包)與變數捕獲語意,是避免陷阱、發揮最大效用的關鍵。

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