foreach中匿名委托的问题

public Form1() { InitializeComponent(); Collection tests = new Collection(); 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); } } 

当我点击按钮女巫文本是’test1’时,消息框将显示’test2’,但我的期望是’test1’。 那么,有人请告诉我代码的原因或错误。

是的 – 你正在关闭循环变量。 lambda表达式中的test引用所有委托中的相同变量,这意味着它将在循环结束时以最终值结束。 获取值的副本并使用它。 你还使用了lambda表达式的一个非常长的forms。 这是固定和缩短的代码:

 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); } 

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