Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 循环执行一系列操作_C#_Action_Enumeration - Fatal编程技术网

C# 循环执行一系列操作

C# 循环执行一系列操作,c#,action,enumeration,C#,Action,Enumeration,我不明白如何循环执行操作列表。当我尝试它时,我得到的值与上一次迭代相同 下面是代码(简化示例): 为什么它在执行操作时总是选择字符串中的最后一个元素? 我如何才能达到预期的输出,即: abc def ghi 您的操作是一个闭包,因此它访问str本身,而不是str的副本: foreach (string str in strings) { var copy = str; // this will do the job actions.Add(new Action(() =>

我不明白如何循环执行
操作
列表。当我尝试它时,我得到的值与上一次迭代相同

下面是代码(简化示例):

为什么它在执行操作时总是选择
字符串中的最后一个元素?
我如何才能达到预期的输出,即:

abc
def
ghi

您的操作是一个闭包,因此它访问
str
本身,而不是
str
的副本:

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

这是一个相当复杂的情况。简单的答案是在将局部变量分配给闭包之前创建其副本:

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

有关详细信息,请参见。

此行为受限制

lambda中存在的变量是参考值副本。这意味着它指向由
str
假设的最新值,在您的案例中是“ghi”。这就是为什么每次调用都会转到相同的内存位置并恢复相同的值

如果您编写代码,就像在提供的答案中一样,您强制
C#
编译器每次重新生成一个new值,这样一个new地址将被传递给labmda,因此每个lambda都有它自己的变量


顺便说一句,如果我没弄错的话,
C#
团队承诺在
C#5.0
中修复这种非自然行为。因此,最好查看他们关于这个主题的博客,以了解未来的更新。

Gah,你赢了。我知道怎么修,但我记不起原因了。关闭!我需要结束+1:)@Joshua就在不久前,当我深入了解时:)。。。我从未意识到,这可能有助于进一步阅读。谢谢。+1很好的解释。值得一提的是,Java是以另一种方式实现的。如果处理
Runnable
(通常)以启动线程,则会将变量复制到新上下文中。这也是为什么Java强制您将它们设置为
final
foreach (string str in strings)
{
    var copy = str; // this will do the job
    actions.Add(new Action(() => { Trace.WriteLine(copy); }));
}
string copy = str;
actions.Add(new Action(() => { Trace.WriteLine(copy); }));