Code Inspection: Access to foreach variable in closure
Consider the following piece of code:
List<string> strings = new List<string>();
foreach (string str in strings)
{
Button btn = new Button();
btn.Click += new EventHandler(delegate { MessageBox.Show(str); });
}
This may appear to be correct but, in actual fact, only the last value of str variable will be used whenever any
button is clicked. The reason for this is that
foreach
unrolls into a
while
loop, but the iteration variable is
defined outside this loop. This means that by the time you show the message box, the value of
str
may have already been iterated to the last value in the strings collection.
A solution to this requires creating an internal reference, e.g.:
foreach (string str in strings)
{
string tmp = str;
Button btn = new Button();
btn.Click += new EventHandler(delegate { MessageBox.Show(tmp); });
}
The code above ensures that the correct reference is passed into the message box.
See Also
Last modified: 19 August 2016