1

Reference Code

public void MyMethod()
{
    string x;
    List sampleList = populateList();

    foreach(MyType myType in sampleList)
    {
        string x;   // why is this not allowed?
        doSomethingwithX(x);
    }
}

I recently started learning C# and today ran into issue with code similar to the above. VS2010 flagged the commented code with this message a local variable named x cannot be declared in this scope because it would give a different meaning to variable x which is already used in parent or current scope to denote something else....

I dont get it...isnt that the whole essence of block statements and scoping...I know i can just change my variable names and go ahead.but i'd like to know WHY?

Xaruth
  • 4,034
  • 3
  • 19
  • 26
oliverdejohnson
  • 1,512
  • 2
  • 14
  • 22

4 Answers4

3

I dont get it...isnt that the whole essence of block statements and scoping...

No, not really. The intention of scoping isn't "to allow you to reuse names".

I know i can just change my variable names and go ahead.but i'd like to know WHY?

It reduces the possibilities for confusing code, basically. There are various situations where C# prevents you from writing code which is confusing. Not as many as we might like, of course, but where there's no clear benefit from allowing something, and a clear benefit from disallowing it, it makes sense to disallow it.

Would you ever want to work with code that had the same local variable name in scope twice? Wouldn't you always prefer the original developer to use a different name? I would - so I'm glad the compiler enforces that.

Note that this doesn't prevent the same local variable name being used twice in the same method - they just can't be in the same scope. So this is valid:

public void Foo()
{
    {
        int x = 10;
        ...
    }

    {
        int x = 10;
        ...
    }
}

But this isn't:

public void Foo()
{
    {
        int x = 10;
        ...
    }

    int x = 10;
    ...
}

If the second example is confusing, you need to bear in mind that the scope of a local variable is the block in which it was declared - not from the declaration point onwards.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • useful official reference text from ECMA-334 15.5.1, Local variable declarations: "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." – jltrem Oct 14 '13 at 14:54
  • simple and clear explanation...thanks – oliverdejohnson Oct 14 '13 at 14:59
2

Previously defined x is still in scope that's why compiler stops you from declaring other one.

You can verify this by limiting the scope of previous variable by wrapping it in curly braces -

  public void MyMethod()
  {
      {
        string x;
      }
      List sampleList = populateList();    
      foreach(MyType myType in sampleList)
      {
          string x;   // This will be fine.
          doSomethingwithX(x);
      }
   }
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
0

The x in the for loop is not visible outwith the loop, but the x you declared at the start of the method is visible within the for loop.

Outwith the loop you have one x but inside it there are two, both of which are being declared

OnABauer
  • 609
  • 4
  • 18
  • yes i many have two x inside the loop but shd be able to differentiate them somehow....possibly with this – oliverdejohnson Oct 14 '13 at 14:41
  • @oliverdejohnson If one were an instance field and one were a local then yes, you could use `this` to refer to the field and omit it to refer to the local. Not coincidentally, such situations would be legal C# code. With two locals of a different scope there *isn't* a way to refer to the outer local. – Servy Oct 14 '13 at 14:42
  • @oliverdejohnson If you have two variables that you want to differentiate then they should have different names. What if you wanted to use the x declared outwith the loop inside it? – OnABauer Oct 14 '13 at 14:45
0

You cannot declare string x; again. .. it will have different meaning. Since string x; is declared inside a method. The scope of x will be available through out the method. . So please declare some other variable inside for each loop. ..

Or you can just x. Instead of declaring again. .

praga2050
  • 729
  • 9
  • 18