foreach中匿名委托的问题

get*_*ing 4 c# foreach delegates

    public Form1()
    {
        InitializeComponent();
        Collection<Test> tests = new Collection<Test>();
        tests.Add(new Test("test1"));
        tests.Add(new Test("test2"));
        foreach (Test test in tests)
        {
            Button button = new Button();
            button.Text = test.name;
            button.Click+=new EventHandler((object obj, EventArgs arg)=>{
                this.CreateTest(test);
            });
            this.flowLayoutPanel1.Controls.Add(button);
        }
    }
    public void CreateTest(Test test)
    {
        MessageBox.Show(test.name);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我点击按钮女巫文本是'test1'时,消息框将显示'test2',但我的期望是'test1'.那么,有人请告诉我为什么或我的代码有什么问题.

Jon*_*eet 14

是的 - 你正在关闭循环变量.将test在lambda表达式中是指在所有的代表相同的变量,这意味着它将结束了在循环结束时的最终值.获取值的副本并使用它.你也使用了lambda表达式的一种非常长的形式.这是固定和缩短的代码:

foreach (Test test in tests)
{
    // Take a copy of the "test" variable so that each iteration
    // creates a delegate capturing a different variable (and hence a
    // different value)
    Test copy = test;
    Button button = new Button();
    button.Text = test.name;
    button.Click += (obj, arg) => CreateTest(copy);
    this.flowLayoutPanel1.Controls.Add(button);
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅Eric Lippert关于此主题的博客文章.