看看这段代码
List<Action> actions = new List<Action>();
for (int variable = 0; variable < 5; ++variable)
{
int myLocalVariable = variable;
actions.Add(() => Console.WriteLine(myLocalVariable));
}
actions.ForEach(s => s.Invoke());
Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)
输出为0 1 2 3 4
看一下IL代码,我倾向于认为编译器只创建了一个myLocalVariable实例.这一事实也证实了在循环中使用局部变量的良好实践.
那么如何委托inside actions.Add()存储循环变量的"最新"版本.
看一下IL代码,我倾向于认为编译器只创建了一个myLocalVariable实例.
不.C#语言规范清楚地表明变量是在循环的每次迭代中实例化的 - 因此每次迭代都有一个单独的变量,它们是分别捕获的.
从C#5规范的7.5.15.2节:
当执行进入变量的范围时,认为局部变量被实例化.例如,当调用以下方法时,对于循环的每次迭代,局部变量x被实例化并初始化三次 - 一次.
Run Code Online (Sandbox Code Playgroud)static void F() { for (int i = 0; i < 3; i++) { int x = i * 2 + 1; ... } }但是,在循环外部移动x的声明会导致单个实例化
x...
当没有捕获时,无法准确地观察局部变量被实例化的频率 - 因为实例化的生命期是不相交的,所以每个瞬时可以简单地使用相同的存储位置.但是,当匿名函数捕获局部变量时,实例化的效果变得明显.
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |