C#局部变量范围

可能重复:
与c#中的范围混淆

看来在C#中,使用本地范围定义的if / else / loop块与该块后面定义的变量冲突的变量 – 请参见代码剪切。 在C / C ++和Java下,等效代码编译得很好。 这是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 */ } 

是的,这就是C#的工作原理。

声明范围时,外部范围内的任何局部变量也是已知的 – 无法限定范围内的局部变量应从外部覆盖局部变量。

这是正常的行为。

Sam Ng不久前写了一篇很好的博客文章: http : //blogs.msdn.com/b/samng/archive/2007/11/09/local-variable-scoping-in-c.aspx

您似乎关注声明的顺序(在if之后重新声明)。

考虑在if之前声明它的情况。 那么你会期望它在这些块的范围内可用。

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

在编译时,实际上并没有“不在范围内”的概念。

实际上,您可以使用裸花括号创建内部范围:

 { int a = 1; } if(true) { int a = 2; // works because the a above is not accessible in this scope } 

已经有一些很好的答案,但我看了一下C#4语言规范来澄清这一点。

我们可以在§1.24中读到有关范围的信息:

范围可以嵌套,内部范围可以从外部范围重新声明名称的含义(但是,这不会消除§1.20强加的限制,即在嵌套块中,不可能使用与封闭块中的局部变量同名。

这是§1.20中引用的部分:

声明定义声明所属的声明空间中的名称。 除了重载成员(第1.23节)之外,如果有两个或多个声明在声明空间中引入具有相同名称的成员,则编译时错误。 声明空间永远不可能包含具有相同名称的不同类型的成员

[…]

请注意,在函数成员或匿名函数体内或在函数成员或匿名函数体内出现的块嵌套在这些函数为其参数声明的局部变量声明空间中。

是。 这是预期的,因为您在本地语句中定义变量。 如果要在类级别定义变量,则会得到不同的结果。