这在C#5.0中正常运行(意味着达到预期):
var actions = new List<Action>(); foreach (var i in Enumerable.Range(0, 10)) { actions.Add(() => Console.WriteLine(i)); } foreach (var act in actions) act();
打印0到9。但是此显示10表示10次:
var actions = new List<Action>(); for (var i = 0; i < 10; i++) { actions.Add(() => Console.WriteLine(i)); } foreach (var act in actions) act();
问题:这是我们在5.0之前的C#版本中遇到的一个问题。因此,我们必须为闭包使用局部循环的占位符,并且现在已在C#5.0中的“ foreach”循环中对其进行了修复。但不要在“ for”循环中!
这背后的原因是什么(也无法解决for循环问题)?
for
这背后的原因是什么?
我将假设您的意思是“为什么for循环也没有更改?”
答案是对于for循环,现有行为是完全合理的。如果您将for循环分成:
…然后循环大致如下:
{ initializer; while (condition) { body; iterator; } }
(当然,iterator也要在continue;语句的末尾执行。)
iterator
continue;
初始化部分在 逻辑上 仅发生一次,因此完全逻辑上只有一个“变量实例化”。此外,在循环的每次迭代中都没有自然的变量“初始”值-不用说for循环 必须具有 在初始化器中声明变量,在条件中进行测试并在迭代器中对其进行修改的形式。您希望像这样的循环做什么:
for (int i = 0, j = 10; i < j; i++) { if (someCondition) { j++; } actions.Add(() => Console.WriteLine(i, j)); }
与此相比,有foreach其循环 看起来 像你宣布每次迭代一个独立的变量。哎呀,变量是只读的,这使它 更像 是一个在两次迭代之间变化的变量。将foreach循环视为在每次迭代中声明一个新的只读变量(其值取自迭代器)非常有意义。
foreach