关于关闭的for和foreach之间有什么区别

huo*_*125 4 c# foreach lambda closures for-loop

演示代码有一些问题.

var values = new List<int>() { 100, 110, 120 };  
var funcs = new List<Func<int>>();  

foreach(var v in values)   
    funcs.Add( ()=>v );  

foreach(var f in funcs)   
    Console.WriteLine(f());  
Run Code Online (Sandbox Code Playgroud)

大多数人认为它是100/110/120.实际上是120/120/120.

但是vs2015和.net 4.5.1的结果将输出 100/110/120 ,而不是 120/120/120 .

当我按如下方式测试代码时,for和之间存在一些差异foreach

var values = new List<int> {100, 110, 120};

var funcs = new List<Func<int>>();
foreach (var v in values)
    funcs.Add(() =>
    {
        Console.WriteLine(v);
        return v;
    } );

foreach (var f in funcs)
    Console.WriteLine(f());

//will throw exception
for (int i=0;i<values.Count;i++)
    funcs.Add(() =>
    {
        Console.WriteLine(values[i]);
        return values[i];
    });

foreach (var f in funcs)
    Console.WriteLine(f());
Run Code Online (Sandbox Code Playgroud)

谁可以给我之间的一些更详细forforeachclosures

Mar*_*ulz 6

这是一个不幸的决定的结果,后来C#团队后悔了.C#5引入的突破性变化最终改变了这种行为.引用Eric Lippert:

在C#5中,foreach循环变量将在逻辑上位于循环体内,因此闭包每次都会得到一个新的副本.

在C#5之前,闭包都引用了相同的变量绑定.因此,所有调用的输出都是相同的,因为它们都访问了同一变量的最新值.

但是,从C#5开始,为每次迭代创建一个新的变量绑定.这是程序员最有可能想要的行为.

  • 值得注意的是,在for循环中,它必须在循环的每次迭代中使用相同的变量. (2认同)