Are Lambda expressions in C# closures?
Solution 1:
A lambda may be implemented using a closure, but it is not itself necessarily a closure.
A closure is "a function together with a referencing environment for the non-local variables of that function.".
When you make a lambda expression that uses variables defined outside of the method, then the lambda must be implemented using a closure. For example:
int i = 42;
Action lambda = () => { Console.WriteLine(i); };
In this case, the compiler generated method must have access to the variable (i
) defined in a completely different scope. In order for this to work, the method it generates is a "function together with the referencing environment" - basically, it's creating a "closure" to retrieve access to the variable.
However, this lambda:
Action lambda2 = () => { Console.WriteLine("Foo"); }
does not rely on any "referencing environment", since it's a fully contained method. In this case, the compiler generates a normal static method, and there is no closure involved at all.
In both cases, the lambda is creating a delegate
("function object"), but it's only creating a closure in the first case, as the lambda doesn't necessarily need to "capture" the referencing environment in all cases.
Solution 2:
Reed's answer is correct; I would just add few additional details:
lambda expressions and anonymous methods both have closure semantics; that is, they "capture" their outer variables and extend the lifetimes of those variables.
anonymous function is the term we use when we mean a lambda expression or an anonymous method. Yes, that is confusing. Sorry. It was the best we could come up with.
a function that can be treated as an object is just a delegate. What makes a lambda a closure is that it captures its outer variables.
lambda expressions converted to expression trees also have closure semantics, interestingly enough. And implementing that correctly was a pain in the neck, I tell you!
"this" is considered an "outer variable" for the purpose of creating a closure even though "this" is not a variable.