220

What is a closure? Do we have them in .NET?

If they do exist in .NET, could you please provide a code snippet (preferably in C#) explaining it?

Drag and Drop
  • 2,672
  • 3
  • 25
  • 37
Developer
  • 17,809
  • 26
  • 66
  • 92

12 Answers12

289

I have an article on this very topic. (It has lots of examples.)

In essence, a closure is a block of code which can be executed at a later time, but which maintains the environment in which it was first created - i.e. it can still use the local variables etc of the method which created it, even after that method has finished executing.

The general feature of closures is implemented in C# by anonymous methods and lambda expressions.

Here's an example using an anonymous method:

using System;

class Test
{
    static void Main()
    {
        Action action = CreateAction();
        action();
        action();
    }

    static Action CreateAction()
    {
        int counter = 0;
        return delegate
        {
            // Yes, it could be done in one statement; 
            // but it is clearer like this.
            counter++;
            Console.WriteLine("counter={0}", counter);
        };
    }
}

Output:

counter=1
counter=2

Here we can see that the action returned by CreateAction still has access to the counter variable, and can indeed increment it, even though CreateAction itself has finished.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Yeah, I was just thinking that (although the article has *lots* of them in.) – Jon Skeet Jan 09 '09 at 16:07
  • Yeah, but it helps to include one here, so that in case your link ever gets stale (heaven forbid), your post here still has some info. – Jason Bunting Jan 09 '09 at 16:08
  • 68
    Thanks Jon. BTW, is there something that you don't know in .NET? :) Who do you go to when you have questions? – Developer Jan 09 '09 at 16:12
  • 51
    There's always more to learn :) I've just finished reading CLR via C# - very informative. Other than that, I usually ask Marc Gravell for WCF/binding/expression trees, and Eric Lippert for C# language things. – Jon Skeet Jan 09 '09 at 16:18
  • To say a closure is "a block of code" isn't technically correct; it has to do with scope hanging around after it was originally defined. A "block of code" is a means to obtaining a closure, but not technically a closure. – Jason Bunting Jan 09 '09 at 16:25
  • I've got the scope part later in the sentence. You could arguably use the word "function" instead of "block of code" but I think the scope part is covered. – Jon Skeet Jan 09 '09 at 16:31
  • 2
    I noticed that, but I still think your statement about it being "a block of code which can be executed at a later time" is simply incorrect - it has nothing to do with execution, more to do with variable values and the scope than execution, per se. – Jason Bunting Jan 09 '09 at 16:34
  • 12
    I'd say that closures aren't useful unless they can be executed, and the "at a later time" highlights the "oddness" of being able to capture the environment (which might otherwise have gone away by execution time). If you only quote *half* the sentence then it's an incomplete answer, of course. – Jon Skeet Jan 09 '09 at 17:03
  • 3
    Something to add, the closure is stored as a reference, even though it's a value type. You'll see this if you play around with functions that return functions :) – NibblyPig Jun 12 '12 at 16:26
  • 1
    @SLC: What do you mean by "it's a value type"? `int` is a value type, but that's not the closure. – Jon Skeet Jun 12 '12 at 16:28
  • I thought the delegate closed over counter, such that when you call the delegate via `action()`, counter is available to be incremented even though it's outside the scope of the delegate. – NibblyPig Jun 12 '12 at 16:33
  • 4
    @SLC: Yes, `counter` is available to be incremented - the compiler generates a class which contains a `counter` field, and any code referring to `counter` ends up going through an instance of that class. – Jon Skeet Jun 12 '12 at 16:40
  • @JonSkeet since int is a value type, `int x = 3; int y = x;` doesn't result in any references being made, x and y are independent. But with counter, the compiler presumably does something because you can make counter a static int, and change it between the two `action()` calls to be 50, and the second `action()` call will output 51. So the delegate must have a reference to counter, which means counter can't be a value type. Does that make sense? – NibblyPig Jun 12 '12 at 16:51
  • 2
    @SLC: In the example I've given, it's a local variable in the source code - but as I say, the compiler creates an instance of a class which *contains* a field. `counter` itself is still stored in a value type, but it's stored *in* an instance of a class. I suggest you compile the above code and then look at it in Reflector with no optimizations :) – Jon Skeet Jun 12 '12 at 16:54
  • 1
    John said that "the compiler generates a class which contains a counter field" and this was key thing for me in order to understand. The comment is not up voted enough in my opinion, anyway thanks a lot for this very interesting discussion. – Olaru Mircea Sep 23 '15 at 07:50
  • It's fine and dandy but I'm having trouble seeing the the practical use for this. Real world applications. It's pretty easy to implement a counter without using a closure. Maybe I'm missing something. – RayLoveless Nov 25 '15 at 04:55
  • @RayLoveless: Did you read the linked article at the top of the answer? There are plenty of examples there. If you've ever used LINQ in C#, that's another prime example... – Jon Skeet Nov 25 '15 at 06:51
  • a closure sounds like a delegate function. The delegate function can be executed at a later time – Golden Lion Nov 23 '22 at 19:04
27

If you are interested in seeing how C# implements Closure read "I know the answer (its 42) blog"

The compiler generates a class in the background to encapsulate the anoymous method and the variable j

[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
    public <>c__DisplayClass2();
    public void <fillFunc>b__0()
    {
       Console.Write("{0} ", this.j);
    }
    public int j;
}

for the function:

static void fillFunc(int count) {
    for (int i = 0; i < count; i++)
    {
        int j = i;
        funcArr[i] = delegate()
                     {
                         Console.Write("{0} ", j);
                     };
    } 
}

Turning it into:

private static void fillFunc(int count)
{
    for (int i = 0; i < count; i++)
    {
        Program.<>c__DisplayClass1 class1 = new Program.<>c__DisplayClass1();
        class1.j = i;
        Program.funcArr[i] = new Func(class1.<fillFunc>b__0);
    }
}
Daniil Grankin
  • 3,841
  • 2
  • 29
  • 39
  • Hi, Daniil - You answer is very useful and i wanted to go beyond your answer and follow up but the link is broken. Unfortunately, my googlefu isn't good enough to find where it moved to. – Knox Jun 07 '20 at 13:27
  • 1
    I've found mirror to mentioned article at https://blog.bonggeek.com/2006/07/anonymous-methods-and-closures-in.html – Danila Polevshchikov Feb 10 '22 at 22:03
  • "I know the answer (its 42) blog" url doesn't work – Razvan May 25 '22 at 10:37
12

Closures are functional values that hold onto variable values from their original scope. C# can use them in the form of anonymous delegates.

For a very simple example, take this C# code:

delegate int testDel();

static void Main(string[] args)
{
    int foo = 4;
    testDel myClosure = delegate()
    {
        return foo;
    };
    int bar = myClosure();
}

At the end of it, bar will be set to 4, and the myClosure delegate can be passed around to be used elsewhere in the program.

Closures can be used for a lot of useful things, like delayed execution or to simplify interfaces - LINQ is mainly built using closures. The most immediate way it comes in handy for most developers is adding event handlers to dynamically created controls - you can use closures to add behavior when the control is instantiated, rather than storing data elsewhere.

Petter Hesselberg
  • 5,062
  • 2
  • 24
  • 42
Dan Monego
  • 9,637
  • 6
  • 37
  • 72
10
Func<int, int> GetMultiplier(int a)
{
     return delegate(int b) { return a * b; } ;
}
//...
var fn2 = GetMultiplier(2);
var fn3 = GetMultiplier(3);
Console.WriteLine(fn2(2));  //outputs 4
Console.WriteLine(fn2(3));  //outputs 6
Console.WriteLine(fn3(2));  //outputs 6
Console.WriteLine(fn3(3));  //outputs 9

A closure is an anonymous function passed outside of the function in which it is created. It maintains any variables from the function in which it is created that it uses.

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
4

A closure is when a function is defined inside another function (or method) and it uses the variables from the parent method. This use of variables which are located in a method and wrapped in a function defined within it, is called a closure.

Mark Seemann has some interesting examples of closures in his blog post where he does a parallel between oop and functional programming.

And to make it more detailed

var workingDirectory = new DirectoryInfo(Environment.CurrentDirectory);//when this variable
Func<int, string> read = id =>
    {
        var path = Path.Combine(workingDirectory.FullName, id + ".txt");//is used inside this function
        return File.ReadAllText(path);
    };//the entire process is called a closure.
Petter Hesselberg
  • 5,062
  • 2
  • 24
  • 42
meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
4

Here is a contrived example for C# which I created from similar code in JavaScript:

public delegate T Iterator<T>() where T : class;

public Iterator<T> CreateIterator<T>(IList<T> x) where T : class
{
    var i = 0; 
    return delegate { return (i < x.Count) ? x[i++] : null; };
}

So, here is some code that shows how to use the above code...

var iterator = CreateIterator(new string[3] { "Foo", "Bar", "Baz"});

// So, although CreateIterator() has been called and returned, the variable 
// "i" within CreateIterator() will live on because of a closure created 
// within that method, so that every time the anonymous delegate returned 
// from it is called (by calling iterator()) it's value will increment.

string currentString;    
currentString = iterator(); // currentString is now "Foo"
currentString = iterator(); // currentString is now "Bar"
currentString = iterator(); // currentString is now "Baz"
currentString = iterator(); // currentString is now null

Hope that is somewhat helpful.

Petter Hesselberg
  • 5,062
  • 2
  • 24
  • 42
Jason Bunting
  • 58,249
  • 14
  • 102
  • 93
  • 1
    You've given an example, but didn't offer a general definition. I gather from your comments here that they are 'more about scope', but surely there's more to it than that? – ladenedge Sep 23 '10 at 15:46
3

Closures are chunks of code that reference a variable outside themselves, (from below them on the stack), that might be called or executed later, (like when an event or delegate is defined, and could get called at some indefinite future point in time)... Because the outside variable that the chunk of code references may gone out of scope (and would otherwise have been lost), the fact that it is referenced by the chunk of code (called a closure) tells the runtime to "hold" that variable in scope until it is no longer needed by the closure chunk of code...

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • As I indicated on someone else's explanation: I hate to be technical, but closure has more to do with scope - a closure can be created in a couple of different ways, but a closure isn't the means, it is the end. – Jason Bunting Jan 09 '09 at 16:23
  • 1
    Closures are relatively new to me, so it's entirely possible I misunderstand, but I get the scope part.. My answer is focused around scope. So I am missing what yr comment is trying to correct... What else can scope be relevant to but some chunk of code? (function, anonymous method, or whatever) – Charles Bretana Jan 09 '09 at 22:11
  • Isn't the key to a closure that some "chunk of runnable code" can access a variable or in-memory value that it syntactically "outside" of it's scope, after that variable should have ordinarily gone "out of scope" or been destroyed? – Charles Bretana Jan 09 '09 at 22:14
  • And @Jason, no worries about being technical, this closure idea is something I took a while to get my head wrapped around, in long discussions with a co-worker, about javascript closures... but he was a Lisp nut and I never quite got through the abstractions in his explanations... – Charles Bretana Jan 09 '09 at 22:18
2

Basically closure is a block of code that you can pass as an argument to a function. C# supports closures in form of anonymous delegates.

Here is a simple example:
List.Find method can accept and execute piece of code (closure) to find list's item.

// Passing a block of code as a function argument
List<int> ints = new List<int> {1, 2, 3};
ints.Find(delegate(int value) { return value == 1; });

Using C#3.0 syntax we can write this as:

ints.Find(value => value == 1);
aku
  • 122,288
  • 32
  • 173
  • 203
  • 1
    I hate to be technical, but closure has more to do with scope - a closure can be created in a couple of different ways, but a closure isn't the means, it is the end. – Jason Bunting Jan 09 '09 at 16:22
2

If you write an inline anonymous method (C#2) or (preferably) a Lambda expression (C#3+), an actual method is still being created. If that code is using an outer-scope local variable - you still need to pass that variable to the method somehow.

e.g. take this Linq Where clause (which is a simple extension method which passes a lambda expression):

var i = 0;
var items = new List<string>
{
    "Hello","World"
};   
var filtered = items.Where(x =>
// this is a predicate, i.e. a Func<T, bool> written as a lambda expression
// which is still a method actually being created for you in compile time 
{
    i++;
    return true;
});

if you want to use i in that lambda expression, you have to pass it to that created method.

So the first question that arises is: should it be passed by value or reference?

Pass by reference is (I guess) more preferable as you get read/write access to that variable (and this is what C# does; I guess the team in Microsoft weighed the pros and cons and went with by-reference; According to Jon Skeet's article, Java went with by-value).

But then another question arises: Where to allocate that i?

Should it actually/naturally be allocated on the stack? Well, if you allocate it on the stack and pass it by reference, there can be situations where it outlives it's own stack frame. Take this example:

static void Main(string[] args)
{
    Outlive();
    var list = whereItems.ToList();
    Console.ReadLine();
}

static IEnumerable<string> whereItems;

static void Outlive()
{
    var i = 0;
    var items = new List<string>
    {
        "Hello","World"
    };            
    whereItems = items.Where(x =>
    {
        i++;
        Console.WriteLine(i);
        return true;
    });            
}

The lambda expression (in the Where clause) again creates a method which refers to an i. If i is allocated on the stack of Outlive, then by the time you enumerate the whereItems, the i used in the generated method will point to the i of Outlive, i.e. to a place in the stack that is no longer accessible.

Ok, so we need it on the heap then.

So what the C# compiler does to support this inline anonymous/lambda, is use what is called "Closures": It creates a class on the Heap called (rather poorly) DisplayClass which has a field containing the i, and the Function that actually uses it.

Something that would be equivalent to this (you can see the IL generated using ILSpy or ILDASM):

class <>c_DisplayClass1
{
    public int i;

    public bool <GetFunc>b__0()
    {
        this.i++;
        Console.WriteLine(i);
        return true;
    }
}

It instantiates that class in your local scope, and replaces any code relating to i or the lambda expression with that closure instance. So - anytime you are using the i in your "local scope" code where i was defined, you are actually using that DisplayClass instance field.

So if I would change the "local" i in the main method, it will actually change _DisplayClass.i ;

i.e.

var i = 0;
var items = new List<string>
{
    "Hello","World"
};  
var filtered = items.Where(x =>
{
    i++;
    return true;
});
filtered.ToList(); // will enumerate filtered, i = 2
i = 10;            // i will be overwriten with 10
filtered.ToList(); // will enumerate filtered again, i = 12
Console.WriteLine(i); // should print out 12

it will print out 12, as "i = 10" goes to that dispalyclass field and changes it just before the 2nd enumeration.

A good source on the topic is this Bart De Smet Pluralsight module (requires registration) (also ignore his erroneous use of the term "Hoisting" - what (I think) he means is that the local variable (i.e. i) is changed to refer to the the new DisplayClass field).


In other news, there seems to be some misconception that "Closures" are related to loops - as I understand "Closures" are NOT a concept related to loops, but rather to anonymous methods / lambda expressions use of local scoped variables - although some trick questions use loops to demonstrate it.

Maverick Meerkat
  • 5,737
  • 3
  • 47
  • 66
0

Just out of the blue,a simple and more understanding answer from the book C# 7.0 nutshell.

Pre-requisit you should know :A lambda expression can reference the local variables and parameters of the method in which it’s defined (outer variables).

static void Main()
{
    int factor = 2;
   //Here factor is the variable that takes part in lambda expression.
    Func<int, int> multiplier = n => n * factor;
    Console.WriteLine (multiplier (3)); // 6
}

Real part:Outer variables referenced by a lambda expression are called captured variables. A lambda expression that captures variables is called a closure.

Last Point to be noted: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
Petter Hesselberg
  • 5,062
  • 2
  • 24
  • 42
Hameed Syed
  • 3,939
  • 2
  • 21
  • 31
0

A closure aims to simplify functional thinking, and it allows the runtime to manage state, releasing extra complexity for the developer. A closure is a first-class function with free variables that are bound in the lexical environment. Behind these buzzwords hides a simple concept: closures are a more convenient way to give functions access to local state and to pass data into background operations. They are special functions that carry an implicit binding to all the nonlocal variables (also called free variables or up-values) referenced. Moreover, a closure allows a function to access one or more nonlocal variables even when invoked outside its immediate lexical scope, and the body of this special function can transport these free variables as a single entity, defined in its enclosing scope. More importantly, a closure encapsulates behavior and passes it around like any other object, granting access to the context in which the closure was created, reading, and updating these values.

enter image description here

mostafa kazemi
  • 514
  • 6
  • 7
-1

A closure is a function, defined within a function, that can access the local variables of it as well as its parent.

public string GetByName(string name)
{
    List<things> theThings = new List<things>();
    return  theThings.Find<things>(t => t.Name == name)[0];
}

so the function inside the find method.

t => t.Name == name

can access the variables inside its scope, t, and the variable name which is in its parents scope. Even though it is executed by the find method as a delegate, from another scope all together.

Petter Hesselberg
  • 5,062
  • 2
  • 24
  • 42
DevelopingChris
  • 39,797
  • 30
  • 87
  • 118
  • 2
    A closure isn't a function, per se, it is more defined by talking about scope than functions. Functions merely assist in keeping the scope around, which causes a closure to be created. But to say a closure is a function isn't technically correct. Sorry to nitpick. :) – Jason Bunting Jan 09 '09 at 16:18