2011-06-25 73 views
3

为什么我不能使用相同的变量名称,例如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中调用“first”索引,而在index_2中调用“second”索引?

如果我有

private void Foo() 
    { 
     for (int index = 0; index < 10; index++) 
     { 
     } 
     // the runtime don't know index here 
    } 

如果运行时不知道下面的for循环,我们为什么不能有一个同名的另一个变量指标?

+0

我不知道官方的原因,但总的来说,C#团队看了一下常见的错误来源,并且在语言中使它们变得非法。另一个例子:没有fallthru switch..case语句,因为缺少的中断是允许这种语言的常见错误。 –

回答

6

即使范围没有,那些变量的声明空间也会重叠。检查埃里克利珀的博客上的话题:

Simple names are not so simple

所有这些规则的目的是为了防止该类缺陷,其中阅读器/代码的维护者被欺骗,以为他们指的是一个名称简单的实体,但实际上是完全意指另一个实体。这些规则特别旨在防止执行应该是安全重构时的令人讨厌的意外。

What's The Difference, Part Two: Scope vs Declaration Space vs Lifetime

的声明空间,相反,是在没有两个实体被允许具有相同的名称程序文本的区域。

变量的声明空间大于其范围以防止这些误导情况。

+0

关闭但不完全。实际上范围也是重叠的,在这个例子中声明空间和范围大小相同。 (尽管有些情况下,声明空间和范围是不同的大小。)请记住,C#中的本地范围是整个块,与C++不同。在这个程序中违反了C#的两条规则。在嵌套局部变量声明空间中声明了两个具有相同名称的变量,并且使用相同的简单名称引用嵌套块中的两个不同的事物。 –

0

第一个索引没有在for循环的范围内定义,这就是为什么它不能在for循环之外重新声明的原因。但是,在for循环中,由于编译器的工作原理,第一个索引是唯一可以访问的地方。

只需将循环外部的索引重命名为index2即可。

回顾一下,两个索引在同一个范围内,一个只是在不同的范围内访问。

6

CodeInChaos基本上是正确的,链接的文章解释了您违反的规则。

你问为什么编译器不能看到差异,但你可以。一个奇怪的问题:显然编译器可以看到的区别。如果编译器无法解决“索引”这两个含义之间的差异,那么它怎么会产生正确的错误?!错误在于有两件事情意味着不同但名称相同,所以编译器当然知道它们是不同的。正是,因为编译器知道“索引”的两个含义是不同的,使它能够正确地给出错误。

继续前进。

有两个局部变量意味着不同的事情是一个糟糕的做法,使错误,这就是为什么有规则,以防止它。如果你真的想这样做,你可以但你需要确保他们的声明空间不重叠。你可以做到这一点通过引入额外的括号:

{ 
    { 
     int index; 
     // blah blah blah 
    } 
    { 
     int index; 
     // blah blah blah 
    } 
} 

因为现在没有空间,其中“指数”既申报意味着两个不同的东西。 (显然,最外局部声明空间是其中“指数”是指两个不同的东西,但索引不是在外部声明空间声明。)

“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) { ... } 
    } 
} 

如此反复,“隐形”支架保持两个局部变量声明ŧ分开。

相关问题