I just came across the most unexpected behavior. I\'m sure there is a good reason it works this way. Can someone help explain this?
Consider this code:
This is well-known and established behavior regarding lambdas, though frequently surprising to those who've encountered it for the first time. The fundamental issue is that your mental model of what a lambda is isn't quite correct.
A lambda is a function that doesn't get run until it's invoked. Your closure binds a reference to that lambda instance, not the value. When you execute your actions in your final foreach loop, that's the first time you're actually following the closed reference to see what it is.
In the first case, you're referencing num, and at that point, the value of num is 4, so of course all your output is 4. In the second case, each lambda has been bound to a different value that was local to the loop each time, and that value isn't changed (it hasn't been GC'd solely because of the lambda reference.) therefore, you get the answer that you expect.
The closure over a local temporary value is actually the standard approach to capture a specific value from a point in time within the lambda.
Adam's link to Eric Lippert's blog provides a more in-depth (and technically accurate) description of what's going on.