Skip navigation

So today a co-worker mentioned how awesome closures are in Javascript. I noted to him that you can do the same in C# 2.0 So I whipped up an example showing how it in action. It was a very contrived example because I wanted to get to the nitty gritty of showing the closure in action rather than setting up a real world example. The simplicity of this sample makes it good as a quick tutorial on closures.

So what is a closure? Basically a closure is a function that includes a snapshot of its surrounding state at the time the function is created. Notice the key word I said created not declared. So how do you go about creating a function in C#? Just as a C# class is a blueprint for objects, a delegate in C# is a blueprint for functions. With C# 2.0, Microsoft developers received the power of closures through the magic of anonymous methods.

You’ve probably read about anonymous methods as a means of making it easier to provide a callback for the Dispatcher (or Control.BeginInvoke before it). If you’ve ever used this method, in essence you were making a closure.

Let’s make the true benefits of closures crystal clear. Without a single static declaration, or the use of another class, I am going to make a console app that can count to ten…twice, and for good measure the app will display a name for each counter.

using System;

using System.Collections.Generic;

using System.Text;

 

namespace ConsoleApplication1

{

    delegate int counter(out String name);

    class Program

    {

For the easy part, we define a delegate that returns an int and takes a String out parameter (or if you’re partial to Strings, it could return a string and take an int as its out parameter. Let’s start our main class for good measure.

        static void Main(string[] args)

        {

            counter count = GetCounter("Counter1");

            counter count2 = GetCounter("Counter2");

            int i = 0;

            String name;

            while (i<10)

            {

                i = count(out name);

                Console.WriteLine(String.Format("{0} is {1}",name,i));

            }

            while (i < 20)

            {

                i = count2(out name);

                Console.WriteLine(String.Format("{0} is {1}",name,i));

                Console.WriteLine(String.Format("{1} is {0}",count(out name),name));

            }

 

            Console.ReadLine();

        }

 Here we’ve got the main program flow…we get two instances of our counter delegate from a function call (more on this later), then we set up two loops that call the delegate and print the results to the console…the first shows the closure in operation…and just to show there’s no funny stuff, the second shows both of them interleaved. The readline is just so the app won’t close right away.

        private static counter GetCounter(String counterName)

        {

            int val = 0;

            counter ret =delegate(out String cName)

            {

                val++;

                cName = counterName;

                return val;

            };

            return ret;

        }

Now we see our closure in action. The GetCounter function takes a string (that names the counter) and returns a counter. The function creates an initial value of zero and declares its return value to be an anonymous method that references the value declared outside of the anonymous method as well as the parameter passed to GetCounter.

Here’s the output:

counter

As you can see, each call to counter1 increments the value from zero up to ten (returning back the parameter passed when the counter was originally retrieved). You can also see that in the second loop, counter2 has it’s own distinct values. And Counter1 retains its values.

So there you have closures in a nutshell. Closures are instantiated methods that retain the state of their environment when they were created. Because that state can be declared within a method, it can prevent a caller from manipulating it even through reflection. Once you get a counter through GetCounter, the only access to its count is by calling the counter. There is also no way to change the counter’s name even through reflection. I’ll leave the rest up to you my studious reader.

Advertisements

2 Comments

  1. Hi,Closures are probably the least well understood feature in JavaScript, so the article is interesting. Even though they\’ve been around in JavaScript for ages (like AJAX actually :-), most JavaScript developers misunderstand them (when they even know that they exist).Interestingly, we will see many more additions to the C# language inspired by JavaScript soon. For example the "var" keyword, the ability to create anonymous objects on the fly, extension methods, etc… Even delegates are only another way to express what JavaScript does: Functions are objects.It\’s one of the many reasons why I love C#. The language has (some of) the dynamism of JavaScript but it remains type safe.HTH,Laurent

  2. Brownie,
     
    That was an insightful article.  Please, keep up the good work :)!
     
    ~Justice


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: