views:

377

answers:

3
var foo = "bar";

new Func<String>(() => 
{
    var foo = ""; // This can't be done in C#. Why is that?

    /* In JavaScript, this is perfectly valid, since this scope (the anonymous
       function) is disconnected from the outer scope, and any variable declared
       within this scope will not affect variables in the outer scope */

})()
+4  A: 

C# captures local variables inside the anonymous function. This is actually a very powerful feature that JavaScript also supports but in a slightly different way.

This concept is what computer scientists call a closure. By capturing local variables they can become part of the state of the function itself thus giving you more flexibility.

Andrew Hare
+11  A: 

Actually, even in javascript it isn't entirely disconnected; javascript allows lexical closures - so without the var, the old value of foo should still be available.

The difference is that javascript chooses to allow you to re-declare the name with a different meaning (in the inner scope). C# chooses not to.

I find the C# version less easy to get confused about! In particular when code (further down in the method) expects to be talking about the "old" variable, and suddenly it starts looking at the "new" one.

Marc Gravell
A: 

Since the code refers to both symbols as "locals", the compiler cannot discover which you are referring to simply by going up the scope chain (local -> member -> type).

FYI, anonymous methods are compiled as classes and are assigned (as properties) any members/locals they access as fields.

Richard Szalay