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 函式塊外部使用跳轉語句也是錯誤的。