Back to results for “Delegates”
C# › Delegates, Events & Lambdas

How does a lambda expression get compiled differently when it captures NO outer variables versus when it DOES capture outer state?

Advanced

Answer

A lambda that captures nothing is compiled as a STATIC, cached method — created once and reused for every call, with zero allocation overhead per invocation. A lambda that captures outer variables requires the compiler to generate a hidden CLOSURE CLASS to hold those captured variables, allocated fresh (typically) each time the enclosing method runs, which has real allocation implications in hot paths.
// No capture: compiled as a cached static delegate, zero per-call allocation
Func<int, int> square = x => x * x;

// Captures 'multiplier': compiler generates a closure class instance per call
int multiplier = 3;
Func<int, int> multiply = x => x * multiplier;
Real-world example Understanding a subtle source of allocation pressure in a hot loop that repeatedly creates lambdas capturing local state.

Common follow-ups: How would you restructure code to avoid this closure allocation in a genuinely performance-critical hot path?