Looping through a list of Actions

情到浓时终转凉″ 提交于 2019-11-28 12:16:11

Your action is a closure, therefore it accesses str itself, not a copy of str:

foreach (string str in strings)
{
    var copy = str; // this will do the job
    actions.Add(new Action(() => { Trace.WriteLine(copy); }));
}

This behaviour is conditionize by Closures.

The variable that is present in your lambda is a reference and not value copy. That means that points to the latest value assumed by str, which is "ghi" in your case. That's why for every call it just goes to the same memory location and recovers, naturally, same value.

If you write the code, like in answers provided, you force a C# compiler to regenerate a new value each time, so a new address will be passed to the labmda, so every lambda will have it's own variable.

By the way, if I'm not mistake, C# team promise to fix this non natural behaviour in C# 5.0. So it's better to check their blog on this subject for future updates.

This is a pretty complicated situation. The short answer is to create a copy of the local variable before assigning it to the closure:

string copy = str;
actions.Add(new Action(() => { Trace.WriteLine(copy); }));

Check out this article on closures for more information.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!