6

Possible Duplicate:
confused with the scope in c#

It appears that in C# a variable defined with the local scope to if/else/loop block is conflicting with variable defined outside following that block - see code snipped. An equivalent code compiles fine under C/C++ and Java. Is this expected behavior in C#?

public void f(){
  if (true) {
    /* local if scope */
    int a = 1;
    System.Console.WriteLine(a);
  } else {
    /* does not conflict with local from the same if/else */
    int a = 2;
    System.Console.WriteLine(a);
  }

  if (true) {
    /* does not conflict with local from the different if */
    int a = 3;
    System.Console.WriteLine(a);
  }

  /* doing this:
   * int a = 5;
   * results in: Error 1 A local variable named 'a' cannot be declared in this scope
   *  because it would give a different meaning to 'a', which is already used in a 
   *  'child' scope to denote something else
   * Which suggests (IMHO incorrectly) that variable 'a' is visible in this scope
   */

  /* doing this: 
   * System.Console.WriteLine(a);
   * results in: Error 1 The name 'a' does not exist in the current context..
   * Which correctly indicates that variable 'a' is not visible in this scope
   */
}
Community
  • 1
  • 1
luchon
  • 61
  • 1
  • 1
  • 2
  • 4
    http://blogs.msdn.com/b/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx – Servy Aug 21 '12 at 18:25
  • possible duplicate of [confused with the scope in c#](http://stackoverflow.com/questions/1196941/confused-with-the-scope-in-c-sharp) and [C# Variable Scoping](http://stackoverflow.com/questions/2049330/c-sharp-variable-scoping). – Raymond Chen Aug 21 '12 at 19:03
  • Thank you Servy. Per blog: 3) Local variables are in scope throughout the entire block in which the declaration occurs. **This is in contrast with C++, in which local variables are in scope in their block only at points after the declaration** – luchon Aug 21 '12 at 20:30

5 Answers5

5

Yes, this is how C# works.

When declaring a scope, any local variable from an outer scope is also known - there is no way to qualify that a local variable within the scope should override the local variable from outside.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 1
    It appears it boils down to "in-scope" definition. In C# unlike in (C++), if local variable is defined inside the block - it is in-scope within entire block regardless of the place of declaration. Whereas, in C++, local variable defined inside the block is in-scope **only at point after the declaration** – luchon Aug 21 '12 at 20:38
4

It looks like you are concerned with the order of declaration (redeclaring a after the if blocks).

Consider the case that it is declared before the if blocks. Then you would expect it to be available within the scope of those blocks.

int a = 1;

if(true)
{
  var b = a + 1; // accessing a from outer scope
  int a = 2; // conflicts
}

There is not really a concept of "not in scope yet" at compile time.

You can actually create an inner scope with just bare curly braces:

{
   int a = 1;
}

if(true)
{
   int a = 2; // works because the a above is not accessible in this scope
}
Jay
  • 56,361
  • 10
  • 99
  • 123
3

That's normal behavior.

Sam Ng wrote a nice blog-post about this a while ago: http://blogs.msdn.com/b/samng/archive/2007/11/09/local-variable-scoping-in-c.aspx

Jensen
  • 3,498
  • 2
  • 26
  • 43
3

There are already some good answers but I gave a look to the C# 4 language specs to clarify this.

We can read in §1.24 about scopes:

Scopes can be nested, and an inner scope may redeclare the meaning of a name from an outer scope (this does not, however, remove the restriction imposed by §1.20 that 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).

And this is the cited part in §1.20:

A declaration defines a name in the declaration space to which the declaration belongs. Except for overloaded members (§1.23), it is a compile-time error to have two or more declarations that introduce members with the same name in a declaration space. It is never possible for a declaration space to contain different kinds of members with the same name

[...]

Note that blocks that occur as or within the body of a function member or anonymous function are nested within the local variable declaration space declared by those functions for their parameters.

Community
  • 1
  • 1
BlackBear
  • 22,411
  • 10
  • 48
  • 86
0

Yes. This is expected because you are defining the variable within the local statement. If you were to define your variable at the class level, you would have different results.

BlackHatSamurai
  • 23,275
  • 22
  • 95
  • 156