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)
谁可以给我之间的一些更详细for和foreach在closures?
这是一个不幸的决定的结果,后来C#团队后悔了.C#5引入的突破性变化最终改变了这种行为.引用Eric Lippert:
在C#5中,foreach循环变量将在逻辑上位于循环体内,因此闭包每次都会得到一个新的副本.
在C#5之前,闭包都引用了相同的变量绑定.因此,所有调用的输出都是相同的,因为它们都访问了同一变量的最新值.
但是,从C#5开始,为每次迭代创建一个新的变量绑定.这是程序员最有可能想要的行为.
| 归档时间: |
|
| 查看次数: |
171 次 |
| 最近记录: |