.NET如何处理范围内的变量

关于什么是幕后快乐的我,我只是小心翼翼。 我有这个代码,当然它不会编译因为我在if语句中创建了hello变量,然后尝试声明它agian。 为什么.NET不允许我这样做? 在这些场景背后可能会让hello变量与声明中的内容相互干扰。

如果变量是在if语句之前声明的话,为什么这可能会干扰它是非常直截了当的。

public void Test() { if (true) { var hello = ""; } var hello = ""; Console.Write(hello); } 

只是为了澄清,这里违反了两条规则。

第一个是嵌套的局部变量声明空间可能不包含两个相同名称的声明。

第二个是嵌套的本地作用域可能不包含两个使用相同简单名称声明的用法来表示两个不同的东西。

这两条规则都被违反了。 请注意,第一条规则基本上是第二条规则的特例。 第二条规则更为笼统; 例如,这也是违规行为:

 class C { int x; void M() { if (whatever) { string x = ""; } x = 10; } } 

这里,简单名称x用于表示一个局部作用域中的this.x和嵌套作用域中的局部变量x 。 这令人困惑; 一个简单的名称需要在整个块中表示相同的内容。 因此,我们将其视为非法。 这是合法的:

 class C { int x; void M() { if (whatever) { string x = ""; } } } 

尽管局部变量是在嵌套在字段范围内的作用域中声明的,但这是允许的,因为字段的作用域不是局部变量声明空间。

这也是合法的:

 class C { int x; void M() { if (whatever) { string x = ""; } else { x = 2; } } } 

因为现在x的两个相互矛盾的用法在它们立即包含的范围的整体中都被一致地使用。 这些范围现在不重叠,因此允许这样做。 (然而,这仍然是一个坏主意。)

这些规则是为了您的安全,但它们可能会令人困惑。 看到

http://blogs.msdn.com/b/ericlippert/archive/tags/declaration+spaces/

http://blogs.msdn.com/b/ericlippert/archive/tags/scope/

有关这些语言function的一些文章。

名称的声明空间扩展到填充整个块,甚至在声明之前。
请参阅Eric Lippert的博客文章 。

来自http://msdn.microsoft.com/en-us/library/aa691132(v=vs.71).aspx :

名称的范围是程序文本的区域,在该区域内可以引用名称声明的实体而无需限定名称。 范围可以嵌套,内部范围可以从外部范围重新声明名称的含义。 ( 但是,这不会消除第3.3节规定的限制,即在嵌套块中,不可能声明一个与封闭块中的局部变量同名的局部变量。 )外部作用域的名称是据说隐藏在内部范围覆盖的程序文本区域中,只有通过限定名称才能访问外部名称。