The LINQ query used here causes the s value to be available outside the scope of the definition where it was originally defined (that is, the CartesianProduct method). This is what is called closure . Due to deferred execution, by the time the LINQ query is actually evaluated (provided that it is eventually evaluated), the allocation method will be completed and s will be “out of scope”, at least in accordance with the traditional rule area. Despite this, in this context it is still “safe” to refer to s .
Closing is very convenient and well-behaved in the traditional functional programming language, where things are naturally immutable. And the fact that C # is the main imperative programming language, where variables are changed by default, is the basis for the problem that leads to this strange work.
By creating an intermediate variable as part of the loop, you actually instruct the compiler to allocate a separate, non-shared variable for each iteration of the LINQ query. Otherwise, each iteration will have the same instance of the variable, which will also be (obviously) the same value ... probably not what you want.
source share