Lambda 可以引用“外部变量”,这些变量位于在其中定义 Lambda 的封闭方法或类型的范围内。 将会存储通过这种方法捕获的变量以供在 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 表达式中的变量范围:
-
捕获的变量将不会被作为垃圾回收,直至引用变量的委托超出范围为止。
-
在外部方法中看不到 Lambda 表达式内引入的变量。
-
Lambda 表达式无法从封闭方法中直接捕获 ref 或 out 参数。
-
Lambda 表达式中的返回语句不会导致封闭方法返回。
-
Lambda 表达式不能包含其目标位于所包含匿名函数主体外部或内部的 goto 语句、break 语句或 continue 语句。