C#本地变量作用域

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
http://blogs.msdn.com/b/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx - Servy
可能是混淆了C#中的作用域C#变量作用域的重复问题。 - Raymond Chen
谢谢Servy。根据博客:3)局部变量在声明所在的整个块中都处于作用域内。这与C++不同,在C++中,局部变量仅在声明后的块中的某些点处于作用域内。 - luchon
5个回答

5

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

在声明作用域时,任何外部作用域中的局部变量也是已知的 - 没有办法限定作用域内的局部变量应该覆盖外部的局部变量。


1
似乎问题归结为“作用域”定义。在C#中,与(C++)不同,如果局部变量在块内定义,则在整个块范围内都是有效的,无论声明的位置如何。而在C++中,在块内定义的局部变量仅在声明之后的点处于作用域内。 - luchon

4

看起来你关心声明顺序(在if块之后重新声明a)。

考虑将其声明放在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
}

3

3
已经有一些好的答案了,但我查看了C# 4语言规范以澄清这个问题。
我们可以在§1.24中读到有关作用域的内容:
作用域可以嵌套,并且内部作用域可以重新声明外部作用域中名称的含义(然而,这并不消除§1.20所施加的限制,在嵌套块内部不可能使用与封闭块中的局部变量同名的局部变量)。
这是在§1.20中引用的部分:
声明将名称定义为其所属的声明空间中的名称。除了重载成员(§1.23)之外,在一个声明空间中引入具有相同名称的成员的两个或更多声明是编译时错误。声明空间永远不可能包含具有相同名称的不同类型的成员
请注意,出现在函数成员或匿名函数的主体中或其中的块是嵌套在由这些函数为其参数声明的局部变量声明空间内的块。

0

是的。这是预期的,因为您正在在局部语句中定义变量。如果您在类级别上定义您的变量,您将会有不同的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接