What is a lambda expression, and what is a closure?
Quick Answer
A lambda is an inline anonymous function: x => x * 2. It becomes a delegate (Func/Action) or, for LINQ providers, an Expression<T>. A closure is created when a lambda uses a variable from the enclosing scope — the compiler “captures” that variable so it stays alive as long as the lambda does.
A lambda is just an inline anonymous function — x => x * 2 — that the compiler turns into a delegate, or an expression tree for something like EF. A closure happens when that lambda references a variable from outside itself; the compiler captures that variable so it lives as long as the lambda does. The important detail is that capture is by reference, so if the outer variable changes later, the lambda sees the new value. That's the source of the old for-loop bug where every lambda ends up seeing the last value — you fix it by copying the loop variable into a local inside the loop.
- Expression lambda:
x => x + 1. Statement lambda:x => { Log(x); return x + 1; }. - Captured variables are captured by reference, not by value — the closure sees later changes.
- The classic loop bug (pre-C# 5 for
foreach, still possible withfor): capturing the loop variable in every iteration's lambda so they all share one variable and see the final value. Fix with a local copy inside the loop. - Closures allocate a small compiler-generated class on the heap; a lambda that captures nothing is cached as a static delegate.
int factor = 2;
Func<int, int> scale = n => n * factor; // captures 'factor'
factor = 10;
Console.WriteLine(scale(5)); // 50, not 10 — sees the new value
var actions = new List<Action>();
for (int i = 0; i < 3; i++)
{
int copy = i; // capture a fresh local
actions.Add(() => Console.Write(copy)); // prints 0 1 2
}