Problem with anonymouse delegate within foreach

夙愿已清 提交于 2020-01-03 17:52:55

问题


    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 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.


回答1:


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.



来源:https://stackoverflow.com/questions/2571398/problem-with-anonymouse-delegate-within-foreach

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!