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

在 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.
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); };

外部變數的參考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# 程式設計手冊)

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

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

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

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

概念

C# 程式設計手冊

其他資源

C# 參考