可能重复:
C#在foreach中重用变量是否有原因?
循环操作列表
今天我遇到了关于C#foreach函数的问题,它并没有像我预期的那样给我正确的结果.这是代码:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int[] data = new int[] { 1, 2, 3, 4, 5 };
List<Func<int>> actions = new List<Func<int>>();
foreach (int x in data)
{
actions.Add(delegate() { return x; });
}
foreach (var foo in actions)
{
Console.WriteLine(foo());
}
Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我在控制台应用程序中运行它并且它在屏幕上打印了5个5.为什么?我只是无法理解.曾经问过一些人,他们只是说这个代码中有封闭,但我对此并不十分清楚,我记得在javascript中,我经常遇到封闭,但在上面的代码中,为什么会有封闭?谢谢.
在C#4中,foreach循环的所有迭代共享相同的变量,因此具有相同的闭包.
规范说:
Run Code Online (Sandbox Code Playgroud)foreach (V v in x) embedded-statement然后扩展到:
Run Code Online (Sandbox Code Playgroud){ E e = ((C)(x)).GetEnumerator(); try { V v; while (e.MoveNext()) { v = (V)(T)e.Current; embedded-statement } } finally { … // Dispose e } }
您可以看到它v在while-loop 外部的块中声明,这会导致此共享行为.
这可能会在C#5中改变.
我们正在进行重大改变.在C#5中,foreach的循环变量将在逻辑上位于循环内部,因此闭包每次都会关闭变量的新副本."for"循环不会改变.