我有这个代码,不明白为什么输出是22!我恐怕应该是01! 有人能解释会发生什么吗?如果列表存储带参数的方法,那么参数应分别为0和1!
List<Action> list = new List<Action>();
for (int i = 0; i < 2; i++)
{
list.Add(() => Console.Write(i));
}
foreach (var it in list)
{
it();
}
答案 0 :(得分:3)
在您的情况下,Console.Write(i)
将在行动调用时使用i
的值。首先在i
循环中递增for
,然后在第二个循环中调用列表中的每个操作。在每个操作i
的调用时刻都有值2 - 所以,您得到22
作为输出。
要获得预期结果,您应创建i
的本地副本并使用它:
for (int i = 0; i < 2; i++)
{
var temp = i;
list.Add(() => Console.Write(temp));
}
答案 1 :(得分:2)
除罗马多斯科赫的anwser外,另一种方法是避免for
。
var list = Enumerable
.Range(0, 2)
.Select<int, Action>(i => () => Console.Write(i));
答案 2 :(得分:1)
闭包捕获变量,而不是值。
在您的代码中,闭包捕获变量i
,而不是每次迭代时在i
中存储的值。当您调用操作时,变量i
的值为2
(因为循环已完成),因此2
将打印两次。
为了避免这种情况,正如其他答案已经指出的那样,您需要每次都创建一个新变量作为解决方法,以便无法捕获值;如果在每次迭代时声明一个新变量,那么捕获变量的结果等同于捕获该值,因为您不会在下一次迭代中更改它。