问题用foreach内匿名者代表 [英] Problem with anonymouse delegate within foreach
问题描述
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);
}
}
,消息框将显示test2,但我的期望是test1。
when i click the button witch text is 'test1', the messagebox will show 'test2',but my expect is 'test1'. So ,would anyone please tell me why or what`s wrong with my code.
推荐答案
Yup - 你'重新关闭循环变量。 lambda表达式中的 test
是指所有代理中的同一个变量,这意味着它将在循环结束时以最终值结束。取一个值的副本并使用它。你也使用一个很长的lambda表达式形式。下面是固定和缩短的代码:
Yup - you're closing over the loop variable. The test
within the lambda expression refers to the same variable in all your delegates, which means it will end up with the final value at the end of the loop. Take a copy of the value and use that. You're also using a pretty longwinded form of the lambda expression. Here's the fixed and shortened code:
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);
}
查看。
See Eric Lippert's blog post on this topic for more information.
这篇关于问题用foreach内匿名者代表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!