Update (2012-10-05): This whole issue has now been fixed in C# 5! The compiler just copies the loop variable for you, if you capture it in a closure. This is actually a breaking change, but a perfectly sensible one. Note that this only affects
foreach. The plain
for loop is unaffected.
Update (2011-06-17): Since I posted this I’ve regularly been told that there’s another solution where you declare a local variable inside the loop and copy the loop variable into it. Thanks, but I know that already! That’s the first solution everyone learns. The idea here was to suggest an alternative solution that works more elegantly, without adding extra clutter.
It’s just an unfortunate side effect of the way foreach works. It reuses the same loop variable each time around the loop, and so that loop variable is created outside the scope of the loop, and so all the delegates you create inside the loop are actually looking at the same variable, not their own local copies.
The executive summary of this post is as follows:
That line of code is all you need to make a blank window open in today’s Visual C++. And if you’re a veteran of the dark days of Petzold and Win32, that has to be viewed as a major improvement. (Even if that % operator does look like gibberish.)