1. 程式人生 > >c#委託和lambda表示式(二)

c#委託和lambda表示式(二)

Lambda表示式

Lambda表示式是一種可用於建立委託或表示式目錄樹型別的匿名函式。通過使用Lambda表示式,可以寫入可作為引數傳遞或作為函式呼叫值返回的本地函式。

若要建立Lambda表示式,需要在Lambda運算子=>左側輸入引數(如果有),然後在另一側輸入表示式或語句塊。例如,Lambda表示式 x => x * x表示名為x的引數並返回x的平方值。

delegate int Del(int i);
static void Main(string[] args)
{
    Del myDelegate = x => x* x;
    int j = myDelegate(3
); //j = 9 }

表示式Lambda

表示式位於=>運算子右側的Lambda表示式稱為”表示式Lambda”。基本形式為: (input parameters) => expression

當lambda只有一個引數時,括號才是可選的;否則括號是必需的。括號內的兩個或更多的輸入引數使用逗號分隔: (x, y)=> x==y

語句Lambda

語句Lambda與表示式Lambda類似, 只是語句在大括號中: (input parameters) => {statement;}

delegate void testDel(string s);
...
testDel myDel = (n) => {string s = n + "" + "world"; Console.WriteLine(s);} myDel("Hello");

Lambda表示式中變數範圍

在定義 lambda 函式的方法內或包含 lambda 表示式的型別內,lambda 可以引用範圍內的外部變數(參見 匿名方法(C# 程式設計指南))。 以這種方式捕獲的變數將進行儲存以備在 lambda 表示式中使用,即使在其他情況下,這些變數將超出範圍並進行垃圾回收。 必須明確地分配外部變數,然後才能在 lambda 表示式中使用該變數。 下面的示例演示這些規則:

delegate bool D();
delegate bool D2(int i);

class Test
{
    D del;
    D2 del2;
    public void TestMethod(int input)
    {
        int j = 0;
        // Initialize the delegates with lambda expressions.
        // Note access to 2 outer variables.
        // del will be invoked within this method.
        del = () => { j = 10;  return j > input; };

        // del2 will be invoked after TestMethod goes out of scope.
        del2 = (x) => {return x == j; };

        // Demonstrate value of j:
        // Output: j = 0 
        // The delegate has not been invoked yet.
        Console.WriteLine("j = {0}", j);        // Invoke the delegate.
        bool boolResult = del();

        // Output: j = 10 b = True
        Console.WriteLine("j = {0}. b = {1}", j, boolResult);
    }

    static void Main()
    {
        Test test = new Test();
        test.TestMethod(5);

        // Prove that del2 still has a copy of
        // local variable j from TestMethod.
        bool result = test.del2(10);

        // Output: True
        Console.WriteLine(result);

        Console.ReadKey();
    }
}

下列規則適用於 lambda 表示式中的變數範圍:
1.捕獲的變數將不會被作為垃圾回收,直至引用變數的委託符合垃圾回收的條件。
2.在外部方法中看不到 lambda 表示式內引入的變數。
3.Lambda 表示式無法從封閉方法中直接捕獲 ref 或 out 引數。
4.Lambda 表示式中的返回語句不會導致封閉方法返回。
5.如果跳轉語句的目標在塊外部,則 lambda 表示式不能包含位於 lambda 函式內部的 goto 語句、break 語句或 continue 語句。 同樣,如果目標在塊內部,則在 lambda 函式塊外部使用跳轉語句也是錯誤的。