6

可能重复:
与 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
   */
}
4

5 回答 5

5

是的,这就是 C# 的工作方式。

声明范围时,外部范围内的任何局部变量也是已知的——没有办法限定范围内的局部变量应该覆盖外部的局部变量。

于 2012-08-21T18:20:53.620 回答
4

看起来您关心声明的顺序(在块a 之后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
}
于 2012-08-21T18:23:17.837 回答
3

这是正常的行为。

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

于 2012-08-21T18:23:09.100 回答
3

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

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

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

这是第 1.20 节中引用的部分:

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

[...]

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

于 2012-08-21T18:43:30.433 回答
0

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

于 2012-08-21T18:21:24.563 回答