14

I've been wondering why in C# using a variable name used previously in a child scope is not allowed. Like this:

if (true)
{
    int i = 1;
}

int i = 2;

Compiling the above code produces an 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

And yet you can't use the variable defined in child scope either. The code above works just fine in Java and I can see no reason why it doesn't in C# too. I'm sure there's a good reason, but what is it?

Carlos
  • 2,503
  • 26
  • 29

4 Answers4

14

It is a design choice made by the designers of C#. It reduces potential ambiguity.

You can use it in one of the two places, inside the if or outside, but you can only define it in one place. Otherwise, you get a compiler error, as you found.

Adam Crossland
  • 14,198
  • 3
  • 44
  • 54
  • I actually thought there would be a "real" reason, 'cause I really can't understand why would anyone make a choice like that. :D But I do see the point and it's nice to know why. – Carlos Jan 13 '10 at 19:21
  • khilon: I really think the real reason is the one I suggested ;^) – Toad Jan 13 '10 at 19:22
  • 1
    @Carlos fyi, the _real_ reason is that all variable declarations are moved to the top of their scope at some point (compilation or JIT). Therefore, the ordering of your scopes in relation to your declarations matters little, a child/ancestor scope conflict will always be a conflict at runtime. The compiler rejects it in advance. – Gusdor Dec 12 '14 at 12:11
3

Something I noticed that was not noted here. This will compile:

for (int i = 0; i < 10; i++)
{
    int a = i * 2;
}
for (int i = 0; i < 5; i++)
{
    int b = i * 2;
}

Taken together, these design decisions seem inconsistent, or at least oddly restrictive and permissive, respectively.

jeffmk
  • 111
  • 2
  • 5
  • "Why I can use same variable in tow sibling scopes" should be either comment or another question. Not really an answer as this post speaks about sibling scopes, unlike original question (child/parent scopes). – Alexei Levenkov Nov 07 '14 at 15:13
  • I agree. I was trying to increase knowledge by pointing out something odd about C# scoping related to the original question, but unfortunately I couldn't post it as a comment since my rep is so low. – jeffmk Nov 14 '14 at 02:16
  • I really cannot see anything wrong, what is wrong with it compiling? – Ghasan غسان Apr 21 '16 at 08:59
1

As Adam Crossland said, it's a design choice - Made to make sure you (or more likely, your fellow developers) dont misunderstand the code.

You often see private instance members prefixed with a "m_" or "_" (eg. _myVar or m_myVar) to avoid confusion..

cwap
  • 11,087
  • 8
  • 47
  • 61
0

to all probability, any variable created in any of the child scope, will be put on the stackframe the moment method is entered.

This way, a similar name in a child scope can not co-exist with a variable name in another child scope.

They could have worked around this of course if they wanted, so I guess it ultimately has to do with design as well.. this way there is less chance for error

Toad
  • 15,593
  • 16
  • 82
  • 128