c# - 循环中匿名方法的不同 "execution context"的问题

标签 c# .net anonymous-methods

我在循环中使用匿名方法时遇到问题。

下面的代码只是为了说明我的问题:

private void Form1_Load(object sender, EventArgs e)
{
    List<string> bassists = new List<string>(){
        "Jaco Pastorius", 
        "Marcus Miller", 
        "Flea", 
        "Vicor Wooten"
    };

    foreach (string item in bassists)
    {
        this.button1.Click += (s, ea) => Output(s, ea, item); 
    }
}

private void Output(object s, EventArgs e, string item)
{
    this.listBox1.Items.Add(item);
}

当我点击按钮时,输出是:

Victor Wooten
Victor Wooten
Victor Wooten
Victor Wooten

代替:

Jaco Pastorius
Marcus Miller
Flea
Vicor Wooten

我的问题的要点是不同的执行上下文。我知道我的例子很愚蠢。

最佳答案

这就是捕获变量问题。通过更改修复它

foreach (string item in bassists)
{
    this.button1.Click += (s, ea) => Output(s, ea, item); 
}

foreach (string item in bassists)
{
    string currentItem = item;
    this.button1.Click += (s, ea) => Output(s, ea, currentItem); 
}

这是对问题的解释:Closing over loop variable considered harmful .通过将局部变量 currentItem 放在循环范围内并关闭它,我们现在捕获该变量而不是循环变量。

关于c# - 循环中匿名方法的不同 "execution context"的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4409495/

相关文章:

c# - 对于链式异步/事件调用是否有有用的设计模式?

c# - 匿名方法如何省略参数列表?

c# - 无参数匿名方法可以分配给有参数委托(delegate)

javascript - 如何根据用户选择更新模型的属性?

c# - 处理递增的 SNMP OID?

c# - 在 .NET 中使用 wsdl 创建对象

c# - 如何切换 .NET 程序集以执行一种方法?

c# - 需要 HttpWebRequest 对象的帮助

c# - 如何比较两个 lambda 表达式?

c# - MVC 部分页面刷新