Capturing Outer Variables - CSharp Custom Type

CSharp examples for Custom Type:Lambda

Introduction

A lambda expression can reference the local variables and parameters of the method in which it's defined. For example:

static void Main()
{
  int factor = 2;
  Func<int, int> multiplier = n => n * factor;
  Console.WriteLine (multiplier (3));           // 6
}

Outer variables referenced by a lambda expression are called captured variables.

A lambda expression that captures variables is called a closure.

Captured variables are evaluated when the delegate is actually invoked, not when the variables were captured:

int factor = 2;
Func<int, int> multiplier = n => n * factor;
factor = 10;
Console.WriteLine (multiplier (3));           // 30

Lambda expressions can themselves update captured variables:

int seed = 0;
Func<int> natural = () => seed++;
Console.WriteLine (natural());           // 0
Console.WriteLine (natural());           // 1
Console.WriteLine (seed);                // 2

Captured variables have their lifetimes extended to that of the delegate.

In the following example, the local variable seed would ordinarily disappear from scope when Natural finished executing.

But because seed has been captured, its lifetime is extended to that of the capturing delegate, natural:

static Func<int> Natural()
{
  int seed = 0;
  return () => seed++;      // Returns a closure
}

static void Main()
{                                                                                                     
  Func<int> natural = Natural();                                                                   
  Console.WriteLine (natural());      // 0                                                         
  Console.WriteLine (natural());      // 1                                                         
}

A local variable instantiated within a lambda expression is unique per invocation of the delegate instance.

static Func<int> Natural()
{
  return() => { int seed = 0; return seed++; };
}

static void Main()
{
  Func<int> natural = Natural();
  Console.WriteLine (natural());           // 0
  Console.WriteLine (natural());           // 0
}

Related Tutorials