Code inspection: Access to foreach variable in closure
First of all, let's make sure that you understand what a closure is. To put it simply, a closure in C# is a lambda expression or an anonymous method that captures some variables from an outer scope. Here is the simplest example:
In the example above, print
will capture the variable myStr
(and not its value) and will only get the value of myStr
when you invoke print()
.
In more complex scenarios, when a closure is defined in a changing context, it may not behave as expected.
One of the situations where it may happen is a closure defined inside a foreach
statement compiled with C# 4.0 (Visual Studio 2010) or earlier versions.
Before C# 5.0 (Visual Studio 2012), the compiler would expand a foreach
to a while
statement with the iteration variable defined outside the loop. Therefore, if this variable was used in a closure, later invocations of this closure would always get the value corresponding to the last iteration of the loop:
ReSharper detects this problem and suggests to fix it by copying the value of the loop variable to the scope where the closure is defined:
This fix makes sure that when you pick an action from myActions
and get the context where this action was created, str
will hold the value of the corresponding iteration.