The LINQ query being used here causes the value of s
to be available outside the scope of where it was originally defined (that is, the CartesianProduct
method). This is what is referred to as a closure. Due to delayed execution, by the time the LINQ query is actually evaluated (assuming it is eventually evaluated), the enclosing method will have been completed and the s
variable will be 'out of scope', at least according to the traditional scope rules. Despite this, it is still 'safe' in this context to refer s
.
Closures are very convenient and well-behaved in a traditional functional programming language where things are naturally immutable. And the fact that C# is foremost an imperative programming language, where variables are mutable by default, is the basis for the issue that results in this strange work-around.
By creating the intermediate variable within the scope of the loop, you are effectively instructing the compiler to allocate a separate, non-shared variable for each iteration of the LINQ query. Otherwise, each iteration will share the same instance of the variable, which will also be (obviously) the same value...probably not what you want.