Problem with anonymouse delegate in 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); } } 

when I press the button, the witch text is "test1", "test2" will appear in the message box, but I expect it to be "test1". So, someone will tell me why or what is wrong with my code.

+4
source share
1 answer

Yup - you close the loop variable. test in the lambda expression refers to the same variable in all your delegates, which means that the final value will be completed at the end of the loop. Take a copy of the value and use it. You also use a rather long form of lambda expression. Here's a 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); } 

For more information see Eric Lippert's blog post .

+14
source

Source: https://habr.com/ru/post/1305935/


All Articles