委托内部循环如何理解本地和循环变量之间的区别

时间:2016-06-09 17:03:14

标签: c# loops closures

看一下代码片段

    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();

输出为0 1 2 3 4

查看IL代码我倾向于认为编译器只创建了一个myLocalVariable实例。这一事实也证实了在循环中使用局部变量的良好实践。

那么如何委托内部的行动。添加()存储&#34;最新的&#34;循环变量的版本。

1 个答案:

答案 0 :(得分:5)

  

查看IL代码我倾向于认为编译器只创建了一个myLocalVariable实例。

不。 C#语言规范清楚地表明变量是在循环的每次迭代中实例化的 - 因此每次迭代都有一个单独的变量,并且它们是单独捕获的。

来自C#5规范的第7.5.15.2节:

  

当执行进入变量的范围时,认为局部变量被实例化。例如,当调用以下方法时,对于循环的每次迭代,局部变量x被实例化并初始化三次 -

static void F() {
    for (int i = 0; i < 3; i++) {
        int x = i * 2 + 1;
        ...
    }
}
     

但是,在循环外移动x的声明会导致x

的单个实例化      

...

     

如果没有捕获,则无法准确地观察实例化局部变量的频率 - 因为实例化的生命周期是不相交的,所以每个瞬时都可以简单地使用相同的存储位置。但是,当匿名函数捕获局部变量时,实例化的效果变得明显。