C# Closure works?
Possible Duplicate:
Is there a reason for C#'s reuse of the variable in a foreach?
Looping through a list of Actions
今天我遇到了一个关于c foreach函数的问题,它没有像我预期的那样给出正确的结果。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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(); } } } |
当我在控制台应用程序中运行它时,屏幕上有5个5。为什么?我就是不明白。有人问过一些人,他们只是说这段代码中有闭包,但我对此不是很清楚,我记得在javascript中,我经常遇到闭包,但在上面的代码中,为什么会有闭包?谢谢。
在C 4中,
说明书上说:
1 foreach (V v in x) embedded-statementis then expanded to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 {
E e = ((C)(x)).GetEnumerator();
try
{
V v;
while (e.MoveNext())
{
v = (V)(T)e.Current;
embedded-statement
}
}
finally
{
… // Dispose e
}
}
可以看到,
这可能会在C 5中改变。
We are taking the breaking change. In C# 5, the loop variable of a foreach will be logically inside the loop, and therefore closures will close over a fresh copy of the variable each time. The"for" loop will not be changed.
http://blogs.msdn.com/b/ericlippet/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx
关键是,当您在
只有在执行