循环中匿名方法的不同“执行上下文”的问题

时间:2010-12-10 13:59:09

标签: 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
  马库斯米勒   跳蚤
  Vicor Wooten

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

3 个答案:

答案 0 :(得分:12)

这是捕获的变量问题。通过更改

来修复它
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放在循环的范围内并关闭它,我们现在捕获该变量而不是循环变量。

答案 1 :(得分:0)

你的问题是你在循环中创建新的处理程序,这是不必要和危险的。

此外,您正在创建一个匿名方法,该方法的循环中的值具有硬编码。更糟糕的是。

答案 2 :(得分:0)

无论如何,杰森的回答是正确的。这是变量捕获的问题。这将主要发生在两种情况下的线程和匿名方法