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.