【发布时间】:2008-11-07 07:26:42
【问题描述】:
我遇到了一个关于 C# 的有趣问题。我有如下代码。
List<Func<int>> actions = new List<Func<int>>();
int variable = 0;
while (variable < 5)
{
actions.Add(() => variable * 2);
++ variable;
}
foreach (var act in actions)
{
Console.WriteLine(act.Invoke());
}
我希望它输出 0、2、4、6、8。然而,它实际上输出了五个 10。
这似乎是由于所有操作都引用了一个捕获的变量。因此,当它们被调用时,它们都有相同的输出。
有没有办法绕过这个限制,让每个动作实例都有自己的捕获变量?
【问题讨论】:
-
另见 Eric Lippert 的博客系列:Closing over the Loop Variable Considered Harmful
-
此外,他们正在更改 C# 5 以在 foreach 中按预期工作。 (重大变化)
-
@Neal: 虽然这个例子在 C# 5 中仍然不能正常工作,因为它仍然输出五个 10s
-
它验证了它在 C# 6.0 (VS 2015) 上直到今天输出了五个 10。我怀疑闭包变量的这种行为是改变的候选者。
Captured variables are always evaluated when the delegate is actually invoked, not when the variables were captured.
标签: c# closures captured-variable