Alex Rivera | Logout

Closures in C# event handler delegates?

Asked 2010-02-09T03:13:12.490
23

I am coming from a functional-programming background at the moment, so forgive me if I do not understand closures in C#.

I have the following code to dynamically generate Buttons that get anonymous event handlers:

for (int i = 0; i < 7; i++)
{
    Button newButton = new Button();

    newButton.Text = "Click me!";

    newButton.Click += delegate(Object sender, EventArgs e)
    {
        MessageBox.Show("I am button number " + i);
    };

    this.Controls.Add(newButton);
}

I expected the text "I am button number " + i to be closed with the value of i at that iteration of the for loop. However, when I actually run the program, every Button says I am button number 7. What am I missing? I am using VS2005.

Edit: So I guess my next question is, how do I capture the value?

Edit
Report

2 Answers

5

You have created seven delegates, but each delegate holds a reference to the same instance of i.

The MessageBox.Show function is only called when the button is clicked. By the time the button has clicked, the loop has completed. So, at this point i will be equaling seven.

Try this:

for (int i = 0; i < 7; i++) 
{ 

    Button newButton = new Button(); 

    newButton.Text = "Click me!"; 

    int iCopy = i; // There will be a new instance of this created each iteration
    newButton.Click += delegate(Object sender, EventArgs e) 
    { 
        MessageBox.Show("I am button number " + iCopy); 
    }; 

    this.Controls.Add(newButton); 
}
answered 2010-02-09T03:19:18.767
1

By the time you click any button, they have all been generated from 1 thru 7, so they will all express the final state of i which is 7.

answered 2010-02-09T03:17:32.950

Your Answer