Patrick Desjardins Blog
Patrick Desjardins picture from a conference

Access to modified closure when having a Linq inside a loop

Posted on: 2011-12-20

If you have Resharper, you can see sometime a warning saying that you "Access to modified closure". If you do not have it, you can still have odd behavior something with the values. In both cases, it means that Linq is accessing a value that might (or not) be modified.

Linq execute delegate functions. If you try :

 var listInteger = new List<int>() { 1, 2, 3, 4, 5 }; //Values

var funcs = new List<Func<int>>(); //Delegate function that take a Integer as parameter

foreach(var v in listInteger) // Add in the list of delegate's functions a function that return the integer value 
{ 
  funcs.Add( ()=>v ); 
} 
foreach(var f in funcs) //Execute functions which should just return the value. 
{ 
  Console.WriteLine(f()); // We expect here to have 1,2,3,4,5 
} 

You will not see 1,2,3,4,5 but 5,5,5,5,5. The reason is that is access a modified variable. The function is not adding the value of v but the pointer to it. This is why it remains on the last value of the loop. But, by using a variable inside the loop, the pointer is to this variable and directly to the good value.

var listInteger = new List<int>() { 1, 2, 3, 4, 5 }; //Values

var funcs = new List<Func<int>>(); //Delegate function that take a Integer as parameter

foreach(var v in listInteger) // Add in the list of delegate's functions a function that return the integer value 
{ 
  var vv = v; funcs.Add( ()=>vv ); 
} 
foreach(var f in funcs) //Execute functions which should just return the value. 
{ 
  Console.WriteLine(f()); // We expect here to have 1,2,3,4,5 
} 

Most of the time, no body will feel this problem because most of the time the Linq won't execute delegate function defined somewhere else but an anonymous function that call directly the value of the variable. But, as a good practice, it's always better when accessing variable that may be changed to create a temporary variable to remove the undesired effect.