6

Possible Duplicate:
Child Scope & CS0136
C# Variable Scoping

Though I have been using C# for quite some time, I have just stumbled upon this error.

If I have the following:

if(true)
{
    int x = 0;
}
int x = 0;

I get an error that says: 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 if I do this:

if(true)
{
    int x = 0;
} 
x = 0;

I get an error that says: The name 'x' does not exist in the current context.

I can understand having one or the other, but why do both of these errors exist? Is there a way around the first option? I find it very annoying.

Thanks.

Community
  • 1
  • 1
Eric
  • 2,098
  • 4
  • 30
  • 44
  • see http://stackoverflow.com/a/296780/870604 – ken2k Jan 19 '12 at 21:13
  • @Comments: Yes, sorry. Guess I should have done some searching first... :-/ – Eric Jan 19 '12 at 21:19
  • @Eric just in case you're really looking to cause yourself, and others, a lot of pain and suffering, here are some examples of x-like characters that are valid identifiers in C#: `int Ҳ, ҳ, א, ẋ, ẍ;` I'm sure that no one will thank you later if you choose to mix these characters into your source code. :) (Just in case it's not clear to anyone reading this...please please please don't use exotic characters like these just so that you can have different variables with similar-looking names) – Dr. Wily's Apprentice Jan 19 '12 at 21:41

2 Answers2

6

Both of these errors exist to stop you from making mistakes or causing your colleagues to want to kill you.

The first fails because it's confusing to have two identically named local variables both in scope at a time.

The second fails because the variable's scope is the if statement, and you're trying to access it outside that scope.

If you want a single variable which you can use both inside and outside the block, you just need to declare it before the block:

int x;
if (true)
{
    x = 0;
}
x = 0;

If you actually want two separate variables to be in scope at the same time (within the block), then give them different names - thereby avoiding later confusion.

EDIT: You can declare multiple local variables with the same name in a single method, but they have to have separate scopes. For example:

public void Foo(IEnumerable<string> values)
{
    double sum = 0;
    foreach (string x in values)
    {
        int z = x.Length;
        sum += z;
    }

    foreach (string x in values)
    {
        double z = double.Parse(x);
        sum += z;
    }
}

Personally I don't tend to use this ability very often - at least not with different types - when the variables have meaningful names and methods are short. But it's absolutely legitimate, and can certainly be useful sometimes.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @Jon: Willing to risk the possibility of death, is it possible to have, say, both an `int` and a `double` named `x` in the same function? – Eric Jan 19 '12 at 21:20
  • 1
    @Eric: Yes, but not in the same scope. Will add an example. – Jon Skeet Jan 19 '12 at 21:21
3

In the first case, the problem is that your int x outside the { } block has a global scope that encloses the context inside { }; therefore you are re-declaring a variable with the same name.

In the second case; x does not exist as it is only defined inside { }

Icarus
  • 63,293
  • 14
  • 100
  • 115