我只是谈到在幕后开心的事情。我有这个代码,当然它不会编译因为我在if语句中创建了hello变量,后来尝试将其声明为agian。为什么选择.NET允许我这样做?在这些场景背后可能会让hello变量与声明中的那个相互干扰。
如果变量是在if语句之前声明的话,为什么这可以干预呢?
public void Test() {
if (true)
{
var hello = "";
}
var hello = "";
Console.Write(hello);
}
答案 0 :(得分:5)
名称的声明空间扩展到填充整个块,甚至在声明之前 请参阅Eric Lippert's blog post。
答案 1 :(得分:4)
只是为了澄清,这里违反了两条规则。
首先,嵌套的局部变量声明空格可能不包含两个同名的声明。
第二个是嵌套的本地作用域可能不包含两个相同的简单名称或声明的用法,意思是两个不同的东西。
违反了这两条规则。请注意,第一条规则基本上是第二条规则的特例。第二条规则更为笼统;例如,这也是违规行为:
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/
有关这些语言功能的一些文章。
答案 2 :(得分:2)
来自http://msdn.microsoft.com/en-us/library/aa691132(v=vs.71).aspx:
名称的范围是程序文本的区域,在该区域内可以引用由名称声明的实体而无需对名称进行限定。范围可以嵌套,内部范围可以从外部范围重新声明名称的含义。 (但是,这不会消除第3.3节规定的限制,即在嵌套块中,不可能声明一个与封闭块中的局部变量同名的局部变量。)然后,外部作用域中的名称被隐藏在内部作用域所覆盖的程序文本区域中,只有通过限定名称才能访问外部名称。