为什么我不能使用相同的变量名,例如方法中的index
?
为什么编译器不能看到不同的,当我明显可以的时候?
示例:
private void Foo()
{
for (int index = 0; index < 10; index++) // "first"-index
{
// I'm in no doubt, use "first"-index here
// (and only within the scope of the for loop)
}
int index = 0; // "second"-index
// I'm in no doubt, use "second"-index here
// (and below)
}
是因为分配是在编译时进行的吗?但是,为什么编译器在引擎盖下只调用index_1的“第一个”索引和index_2的“第二个”索引?
如果我有
private void Foo()
{
for (int index = 0; index < 10; index++)
{
}
// the runtime don't know index here
}
如果运行时不知道for循环下面的索引,为什么我们不能有另一个具有该名称的变量?
答案 0 :(得分:6)
即使范围没有,这些变量的声明空间也会重叠。检查Eric Lippert关于该主题的博客:
Simple names are not so simple
所有这些规则的目的是防止代码的读者/维护者被欺骗的类别被认为他们指的是一个具有简单名称的实体,但实际上是意外地引用另一个实体完全。这些规则特别旨在防止在执行应该是安全的重构时出现令人讨厌的意外。
What's The Difference, Part Two: Scope vs Declaration Space vs Lifetime
相反,声明空间是程序文本的一个区域,其中不允许两个实体具有相同的名称。
变量的声明空间大于其范围,以防止这些误导性情况。
答案 1 :(得分:6)
CodeInChaos基本上是正确的,链接的文章解释了您违反的规则。
你问为什么编译器无法看到差异,但你可以。一个奇怪的问题:显然编译器可以看到差异。如果编译器无法解决“索引”这两个含义之间的差异,那么如何正确地产生错误?!错误是有两个东西意味着不同但名称相同的东西,因此编译器当然知道它们是不同的。正是因为编译器知道“索引”的两个含义是不同的,这使得它能够正确地给出错误。
继续前进。
有两个局部变量意味着不同的东西是一个不好的做法,会产生错误,这就是为什么有规则阻止它。如果你真的想这样做,你可以但要求你确保他们的声明空格不重叠。你可以通过引入额外的括号来做到这一点:
{
{
int index;
// blah blah blah
}
{
int index;
// blah blah blah
}
}
因为现在没有“index”被声明为的空间而意味着两个不同的东西。 (显然,最外层的局部声明空间是“索引”意味着两个不同的东西,但索引在外部声明空间中不是声明。)
“for”和“foreach”循环被视为围绕整个事物具有隐形括号,所以这是合法的:
{
for(int index = 0; index <= 10; ++index) {...}
for(int index = 0; index <= 10; ++index) {...}
}
编译器假装您实际编写了
{
{
int index = 0;
while(index <= 10) { ... }
}
{
int index = 0;
while(index <= 10) { ... }
}
}
同样,“不可见”括号使两个局部变量声明保持文本分离。
答案 2 :(得分:0)
第一个索引没有在for循环的范围内定义,这就是为什么它不能在for循环之外重新声明的原因。然而,在for循环中,由于编译器的工作原理,它是唯一可以访问第一个索引的地方。
只需将循环外的索引重命名为index2。
总结一下,两个索引都在同一个范围内,一个只是在不同的范围内访问。