Lambda表达式可以引用本地变量以及其所在的方法参数:
static void Main()
{
int factor = 2;
Func<int, int> multiplier = n => n * factor;
Console.WriteLine (multiplier (3)); // 6
}
Lambda表达式引用的外部变量被称为被捕获的(captured)变量。捕获变量的Lambda表达式称为一个闭包(closure)。被捕获的变量只有在真正通过委托被调用的时候才会被赋值,而不是在其被捕获的时候。
int factor = 2;
Func<int, int> multiplier = n => n * factor;
factor = 10;
Console.WriteLine (multiplier (3)); // 30
Lambda表达式可以自己更新其捕获的变量:
int seed = 0;
Func<int> natural = () => seed++;
Console.WriteLine (natural()); // 0
Console.WriteLine (natural()); // 1
Console.WriteLine (seed); // 2
被捕获的变量的生命周期可以根据委托做相应的延长。下面的例子中,本地变量seed本应该在Natural方法执行完成后就消失掉。但因为它被捕获了,其生命周期也相应地随着捕获它的委托(natural)被延长了
static Func<int> Natural()
{
int seed = 0;
return () => seed++; // Returns a closure
}
static void Main()
{
Func<int> natural = Natural();
Console.WriteLine (natural()); // 0
Console.WriteLine (natural()); // 1
}
在Lambda表达式中初始化的本地变量每次委托调用都是独一无二的。如果我们重构之前例子中的代码,在lambda表达式中初始化seed变量, 我们就会得到一个不同的结果(在这个例子中,这个结果不是我们想要的):
static Func<int> Natural()
{
return() => { int seed = 0; return seed++; };
}
static void Main()
{
Func<int> natural = Natural();
Console.WriteLine (natural()); // 0
Console.WriteLine (natural()); // 0
}