C# issue with dynamically linking variable value in delegate

I have a GUI setup code in my game, like:

for (int i = 0; i < count; i++)
{
    ...
    Button button = new Button();
    ...
    button.handler = delegate { selectedIndex = i; };
    gui.Add(button);
    ...
}

I want to make button changing selectedIndex to current value of i, that was on it's creation. I.e. button0 changes it to 0, button1 to 1 and so on. But it looks like it dinamycally link value in delegate to i variable and all buttons changes selectedIndex to count + 1. How to fix it?

Jon Skeet
people
quotationmark

You're running into the common problem of what gets captured in an anonymous function. You're capturing i in the delegate, and that value changes over the course of your loop.

You need a copy of i:

for (int i = 0; i < count; i++)
{
    int copy = i;
    ...
    Button button = new Button();
    ...
    button.handler = delegate { selectedIndex = copy; };
    gui.Add(button);
    ...
}

Note that foreach loops had the same problem in C# 4, but in C# 5 the iteration variable in a foreach loop is a "fresh" variable on each iteration.

people

See more on this question at Stackoverflow