Why can't a duplicate variable name be declared in a nested local scope?

Based on this recent question, I don't understand the answer provided. Seems like you should be able to do something like this, since their scopes do not overlap

static void Main()
{
  {
    int i;
  }
  int i;
}

This code fails to compile with the following error:

A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else


I don't think any of the answers so far have quite got the crucial line from the spec.

From section 8.5.1:

The scope of a local variable declared in a local-variable-declaration is the block in which the declaration occurs. It is an error to refer to a local variable in a textual position that precedes the local-variable-declarator of the local variable. Within the scope of a local variable, it is a compile-time error to declare another local variable or constant with the same name.

(Emphasis mine.)

In other words, the scope for the "later" variable includes the part of the block before the declaration - i.e. it includes the "inner" block containing the "earlier" variable.

You can't refer to the later variable in a place earlier than its declaration - but it's still in scope.


"The scope of local or constant variable extends to the end of the current block. You cannot declare another local variable with the same name in the current block or in any nested blocks." C# 3.0 in a Nutshell, http://www.amazon.com/3-0-Nutshell-Desktop-Reference-OReilly/dp/0596527578/

"The local variable declaration space of a block includes any nested blocks. Thus, within a nested block it is not possible to declare a local variable with the same name as a local variable in an enclosing block." Variable Scopes, MSDN, http://msdn.microsoft.com/en-us/library/aa691107%28v=vs.71%29.aspx

On a side note, this is quite the opposite that of JavaScript and F# scoping rules.