Closures in C#

C# supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

using System;

class Program
{
    // This function intSeq returns another function, which
    // we define anonymously in the body of intSeq. The
    // returned function closes over the variable i to
    // form a closure.
    static Func<int> IntSeq()
    {
        int i = 0;
        return () =>
        {
            i++;
            return i;
        };
    }

    static void Main()
    {
        // We call IntSeq, assigning the result (a function)
        // to nextInt. This function value captures its
        // own i value, which will be updated each time
        // we call nextInt.
        Func<int> nextInt = IntSeq();

        // See the effect of the closure by calling nextInt
        // a few times.
        Console.WriteLine(nextInt());
        Console.WriteLine(nextInt());
        Console.WriteLine(nextInt());

        // To confirm that the state is unique to that
        // particular function, create and test a new one.
        Func<int> newInts = IntSeq();
        Console.WriteLine(newInts());
    }
}

To run the program, compile and execute it:

$ csc Program.cs
$ mono Program.exe
1
2
3
1

In C#, closures are implemented using lambda expressions and delegate types. The Func<int> delegate represents a function that takes no parameters and returns an integer.

The IntSeq method returns a closure that increments and returns a counter. Each time you call IntSeq, you get a new closure with its own independent counter.

The last feature of functions we’ll look at for now is recursion.