When using lambda expressions or anonymous methods in C#, we have to be wary of the access to modified closure pitfall. For example:
foreach (var s
In C# 5.0, this problem is fixed and you can close over loop variables and get the results you expect.
The language specification says:
8.8.4 The foreach statement
(...)
A foreach statement of the form
foreach (V v in x) embedded-statementis then expanded to:
{ E e = ((C)(x)).GetEnumerator(); try { while (e.MoveNext()) { V v = (V)(T)e.Current; embedded-statement } } finally { … // Dispose e } }(...)
The placement of
vinside the while loop is important for how it is captured by any anonymous function occurring in the embedded-statement. For example:int[] values = { 7, 9, 13 }; Action f = null; foreach (var value in values) { if (f == null) f = () => Console.WriteLine("First value: " + value); } f();If
vwas declared outside of the while loop, it would be shared among all iterations, and its value after the for loop would be the final value,13, which is what the invocation offwould print. Instead, because each iteration has its own variablev, the one captured byfin the first iteration will continue to hold the value7, which is what will be printed. (Note: earlier versions of C# declaredvoutside of the while loop.)