dem*_*key 8 c# action enumeration
我无法理解如何遍历Action
列表.当我尝试它时,我最终得到的值与前一次迭代相同.
这是代码(简化示例):
string[] strings = { "abc", "def", "ghi" };
var actions = new List<Action>();
foreach (string str in strings)
actions.Add(new Action(() => { Trace.WriteLine(str); }));
foreach (var action in actions)
action();
Run Code Online (Sandbox Code Playgroud)
输出:
ghi
ghi
ghi
Run Code Online (Sandbox Code Playgroud)
为什么在strings
执行操作时始终选择最终元素?
我怎样才能实现所需的输出:
abc
def
ghi
Run Code Online (Sandbox Code Playgroud)
Mat*_*eid 15
你的动作是一个闭包,因此它访问str
自己,而不是一个副本str
:
foreach (string str in strings)
{
var copy = str; // this will do the job
actions.Add(new Action(() => { Trace.WriteLine(copy); }));
}
Run Code Online (Sandbox Code Playgroud)
这种行为受Closures 制约。
存在于 lambda 中的变量是引用而不是值副本。这意味着指向 假定的最新值str
,在您的情况下为“ghi”。这就是为什么每次调用它都会转到相同的内存位置并自然地恢复相同的值。
如果您编写代码,就像在提供的答案中一样,您会强制C#
编译器每次重新生成一个新值,因此将向 labmda 传递一个新地址,因此每个 lambda 都会有它自己的变量。
顺便说一句,如果我没有弄错,C#
团队承诺来解决这个非天然的行为C# 5.0
。所以最好查看他们关于这个主题的博客以获取未来的更新。
归档时间: |
|
查看次数: |
9179 次 |
最近记录: |