Closure in Javascript vs C#

Check out my new course Learn you some Lambda best practice for great good! and learn the best practices for performance, cost, security, resilience, observability and scalability.

Java vs C#

As Jon Skeet pointed out in this excellent article on closures, the strategies of capturing the execution context which the behaviour is bound to different between Java and C#. C# captures the variable itself, whereas Java captures the value of the variable. To illustrate the difference, here’s Jon’s original example in C#:

// First build a list of actions
List<Action> actions = new List<Action>();

for (int counter = 0; counter < 10; counter++)
{
    actions.Add(() => Console.WriteLine(counter));
}

// Then execute them
foreach (Action action in actions)
{
    action();
}

This code actually writes 10 ten times instead of 0 to 9 because the context the actions are bound to is the variable counter, and at the time of execution the value of counter is 10 hence why each Action delegate writes 10 instead of the value of counter at the time the Action delegate was created.

The equivalent code in Java would print 0 to 9 because Java’s closure implementation captures the value of the variable instead.

However, as Jon pointed out, whilst Java’s implementation is more intuitive and easier to understand (less WTF bugs), C#’s implementation is more flexible as you can just easily mimic the effect of capturing the variable’s value by using a local variable:

// First build a list of actions
List<Action> actions = new List<Action>();

for (int counter = 0; counter < 10; counter++)
{
    int copy = counter;
    actions.Add(() => Console.WriteLine(copy));
}

// Then execute them
foreach (Action action in actions)
{
    action();
}

Javascipt vs C# (Updated 16/01/2011)

Thanks for Jens for pointing out my initial incorrect assessment (see comment), so I revised my test and used a more straight forward test using just one private variable:

function test () {
    var i = 10;
    
    // create the closure
    var func = function () { return i; };

    // 10
    alert(func());

    i = 11;
    // 11? or 10?
    alert(func());
}

The test here is simple, we create a function func which returns the value of the private variable i, whose value is then changed later on. If Javascript captures the value of the variable then the second time func is invoke the alert message would still be 10, otherwise it’ll be 11 which is the current value of i.

And the answer is?

.

.

.

Javascript captures the reference of the variable, and the second alert message is 11.

References:

Jon Skeet’s article on closures

Article on Javascript closures

Liked this article? Support me on Patreon and get direct help from me via a private Slack channel or 1-2-1 mentoring.
Subscribe to my newsletter


Hi, I’m Yan. I’m an AWS Serverless Hero and the author of Production-Ready Serverless.

I specialise in rapidly transitioning teams to serverless and building production-ready services on AWS.

Are you struggling with serverless or need guidance on best practices? Do you want someone to review your architecture and help you avoid costly mistakes down the line? Whatever the case, I’m here to help.

Hire me.


Check out my new course, Learn you some Lambda best practice for great good! In this course, you will learn best practices for working with AWS Lambda in terms of performance, cost, security, scalability, resilience and observability. Enrol now and enjoy a special preorder price of £9.99 (~$13).

Start Learning


Are you working with Serverless and looking for expert training to level-up your skills? Or are you looking for a solid foundation to start from? Look no further, register for my Production-Ready Serverless workshop to learn how to build production-grade Serverless applications!

Find a workshop near you