捕获变量时,会创建一个包装类
例子:
1: static void Main(string[] args)
2: {
3: Console.WriteLine("Variable Capturing");
4:
5: string name = "Matthew";
6: Func<String> capture = () => name;
7:
8: name = "Mallory";
9:
10: Print(capture);
11:
12: }
13:
14: static void Print(Func<string> capture)
15: {
16: Console.WriteLine(capture());
17: }变量“name”在第 6 行的 lambda 表达式内被捕获。然后在第 8 行修改相同的变量。然后在第 10 行,我们将 lambda 表达式传递给 Print 函数,然后打印出捕获的变量。当代码运行时,输出将是:
Mallory
值得注意的是,虽然变量“name”在第 6 行被“捕获”,但它反映了第 8 行对局部变量“name”所做的更改。要了解它是如何工作的,让我们展示一下 C# 编译器将大致变成什么之前的代码进去。(我将匿名类型的名称更改为更具可读性):
1: public class Capture
2: {
3: public string name;
4:
5: public string Lambda()
6: {
7: return this.name;
8: }
9:
10: }
11:
12: static void Main(string[] args)
13: {
14: Capture capture = new Capture();
15:
16: Console.WriteLine("Variable Capturing");
17:
18: capture.name = "Matthew";
19:
20: capture.name = "Mallory";
21:
22: Print(capture.Lambda);
23: }
24:
25: static void Print(Func<string> capture)
26: {
27: Console.WriteLine(capture());
28: }创建了一个名为“Capture”的新类。原始代码中所有出现的变量“name”都被替换为对捕获类的“name”成员的字段访问。此外,lambda 表达式变成了我称之为 Lambda 的捕获类上的一个方法(是的,这就是所有匿名委托和 lambda 表达式)。这就是变量的更改如何在 lambda 表达式中持久化,对变量的每次更改只会修改 Capture 类中的字段。


少有人走的路


















