5

Not sure if this is because the C# compiler is extra picky, but I try to do this in C#:

public static void Main()
{
    bool result = true; // some dummy value
    if(result)
    {
        int x = 5;
        Console.WriteLine(x);
    }

    int x = 10;
    Console.WriteLine(x);
}

The compiler complains that the variable name "x" is already being used:

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

And I understand that it thinks it's a scope issue, but why does it think that?

If I reproduce the same code in Java, there are no problems.

Ghasem
  • 14,455
  • 21
  • 138
  • 171
David Mordigal
  • 399
  • 3
  • 19

4 Answers4

2

Not every {} starts a new scope. The integer declared in the if block is still on the same stack as the function.

Black Frog
  • 11,595
  • 1
  • 35
  • 66
1

From MSDN Compiler Error CS0136

For each occurrence of a given identifier as a simple-name in an expression or declarator, within the local variable declaration space (§3.3) immediately enclosing that occurrence, every other occurrence of the same identifier as a simple-name in an expression or declarator must refer to the same entity. This rule ensures that the meaning of a name is always the same within a given block, switch block, for-, foreach- or using-statement, or anonymous function.

As a second reference, check Variable scope confusion in C# answers which you can find good information in.

You are allowed to use the same variable name in non-overlapping scopes. If one scope overlaps another, though, you cannot have the same variable declared in both. The reason for that is to prevent you from accidentally using an already-used variable name in an inner scope

Community
  • 1
  • 1
Ghasem
  • 14,455
  • 21
  • 138
  • 171
1

As @BlackFrog correctly points out, each { } does not start a new scope. From the C# Language Specification, §3.3:

• Each method declaration, indexer declaration, operator declaration, instance constructor declaration and anonymous function creates a new declaration space called a local variable declaration space. Names are introduced into this declaration space through formal parameters (fixed-parameters and parameter-arrays) and type-parameters. The body of the function member or anonymous function, if any, is considered to be nested within the local variable declaration space. It is an error for a local variable declaration space and a nested local variable declaration space to contain elements with the same name.

(emphasis mine)

AGB
  • 2,230
  • 1
  • 14
  • 21
0

I think it's more obvious why if you move the outer declaration of x above the if statement.

public static void Main()
{
    bool result = true; // some dummy value

    int x = 10;

    if(result)
    {
        //references x in parent scope
        x = 5;
        //x is already defined, can't define again
        int x = 5;
        Console.WriteLine(x);
    }

    Console.WriteLine(x);
}

Clearly the compiler would see x as being a variable which is already defined inside the if statement when the code tries to declare it again.

mclaassen
  • 5,018
  • 4
  • 30
  • 52
  • Yeah, and that would be the same case in Java. But order matters in Java - the example above works there. I guess the C# compiler is a little pickier. – David Mordigal Feb 13 '16 at 04:36
  • Ah yes, forgot you said it works in Java. The java compiler obviously doesn't have the same rules as listed in the other answers. – mclaassen Feb 13 '16 at 04:45