Resharper: Access to the modified closure, simplified.

The following code makes Resharper to nag with “Access to the modified closure”!


var list = new int[]{1,2,3,4,5};
var listdoubled = new List<int>();
foreach(var item in list)
   {
      listdoubled.Add( item * 2 );
   }
listdoubled.ForEach( n => Console.WriteLn(n) );

The above coed looks absolutely perfect, but why reshaper is so concerned about it? Below is what can go wrong when you access the modified closure.


var list = new int[]{1,2,3,4,5};
var listdoubled = new List<delegate>();
foreach(var item in list)
{
listdoubled.Add( () => {Console.WriteLn( item * 2 ) ;} );
}
listdoubled.ForEach( n => n() );

The first piece of code will print this:

2
4
6
8
10

But the second piece of code will print this:

10
10
10
10
10

Why? Because the variable in the foreach loop is defined once and modified each time. If you change the code like this, you get the correct behavior.


var list = new int[]{1,2,3,4,5};
var listdoubled = new List<delegate>();
foreach(var item in list)
{
var itemWithNewScope = item;
listdoubled.Add( () => {Console.WriteLn( itemWithNewScope * 2 ) ;} );
}
listdoubled.ForEach( n => n() );