共用方式為


匿名方法 (C# 程式設計手冊)

更新:2007 年 11 月

在 C# 2.0 以前的版本中,宣告委派 (Delegate) 的唯一方式是使用具名方法。C# 2.0 引進了匿名方法 (Anonymous Method),在 C# 3.0 (含) 以後版本,則以 Lambda 運算式取代匿名方法來做為撰寫內嵌 (Inline) 程式碼的慣用方式。不過,本主題中關於匿名方法的資訊也同時適用於 Lambda 運算式。在某個特定情況下,匿名方法會提供 Lambda 運算式未提供的功能。匿名方法讓您能夠省略參數清單,而這表示匿名方法可以轉換為具有各種簽章的委派。Lambda 運算式並未提供這項功能。如需 Lambda 運算式的專屬詳細資訊,請參閱 Lambda 運算式 (C# 程式設計手冊)

基本上,建立匿名方法是將程式碼區塊當做委派參數傳遞的一種方式。以下為兩個範例:

// Create a handler for a click event
button1.Click += delegate(System.Object o, System.EventArgs e)
                   { System.Windows.Forms.MessageBox.Show("Click!"); };
// Create a delegate instance
delegate void Del(int x);

// Instantiate the delegate using an anonymous method
Del d = delegate(int k) { /* ... */ };

在使用匿名方法時,因為不需要建立個別的方法,所以您可以減少在具現化委派時所需要另外撰寫的程式碼。

例如,當需要建立似乎不太有必要的方法時,就可以指定程式碼區塊來替代委派。啟動新執行緒時就是個好例子。這個類別會建立執行緒,並會包含執行緒所執行的程式碼,而不需要為委派建立額外方法。

void StartThread()
{
    System.Threading.Thread t1 = new System.Threading.Thread
      (delegate()
            {
                System.Console.Write("Hello, ");
                System.Console.WriteLine("World!");
            });
    t1.Start();
}

備註

匿名方法之參數的範圍就是 anonymous-method-block。

如果目標位於匿名方法區塊外部,則在區塊內部便不能放入跳躍陳述式 (Jump Statement),例如 gotobreakcontinue。如果目標位於匿名方法區塊內部,則在區塊外部也不能出現跳躍陳述式,例如 goto、break 或 continue。

若區域變數和參數的範圍包含匿名方法宣告,這些變數和參數便稱為匿名方法的 outer 變數。例如,在下面一段程式碼中,n 即為外部變數:

int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };

與區域變數不同的是,所擷取變數的存留期 (Lifetime) 會延長,直到參考匿名方法的委派可進行記憶體回收為止。n 的參考是在建立委派時所擷取。

匿名方法不能存取外部範圍的 refout 參數。

在 anonymous-method-block 內部不能存取任何 Unsafe 程式碼。

is 運算子的左邊不允許使用匿名方法。

範例

下列範例會示範具現化委派的兩種方式:

  • 將一個匿名方法與該委派建立關聯

  • 將一個具名的方法 (DoWork) 與該委派建立關聯

該委派被叫用 (Invoke) 時都會顯示訊息。

// Declare a delegate
delegate void Printer(string s);

class TestClass
{
    static void Main()
    {
        // Instatiate the delegate type using an anonymous method:
        Printer p = delegate(string j)
        {
            System.Console.WriteLine(j);
        };

        // Results from the anonymous delegate call:
        p("The delegate using the anonymous method is called.");

        // The delegate instantiation using a named method "DoWork":
        p = new Printer(TestClass.DoWork);

        // Results from the old style delegate call:
        p("The delegate using the named method is called.");
    }

    // The method associated with the named delegate:
    static void DoWork(string k)
    {
        System.Console.WriteLine(k);
    }
}
/* Output:
    The delegate using the anonymous method is called.
    The delegate using the named method is called.
*/

請參閱

概念

C# 程式設計手冊

參考

委派 (C# 程式設計手冊)

Lambda 運算式 (C# 程式設計手冊)

Unsafe 程式碼和指標 (C# 程式設計手冊)

方法 (C# 程式設計手冊)

使用具名和匿名方法委派的比較 (C# 程式設計手冊)

其他資源

C# 參考