可以';不要在方法中使用相同的变量名

本文关键字:变量名 方法 可以 | 更新日期: 2023-09-27 18:00:15

为什么我不能在方法中使用相同的变量名,例如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循环下面的索引,为什么我们不能有另一个同名的变量呢?

可以';不要在方法中使用相同的变量名

即使作用域没有,这些变量的声明空间也会重叠。查看Eric Lippert关于的博客

简单的名字不是那么简单的

所有这些规则的目的是防止代码的读取器/维护者被欺骗,以为他们用简单的名称引用了一个实体,但实际上却意外地完全引用了另一个实体。这些规则特别设计用于在执行本应安全的重构时防止令人讨厌的意外。

区别是什么,第二部分:范围与声明空间与寿命

相反,声明空间是程序文本的一个区域,其中不允许两个实体具有相同的名称。

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

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

你会问为什么编译器看不到区别,但你可以。一个奇怪的问题:显然编译器可以看到差异。如果编译器不能计算出"index"的两个含义之间的区别,那么它怎么能正确地产生错误?!错误在于,有两个意思不同但名称相同的东西,所以编译器当然知道它们是不同的。正是,因为编译器知道"索引"的两个含义不同,才能够正确地给出错误。

继续前进。

有两个表示不同事物的局部变量是一种糟糕的做法,会产生错误,这就是为什么有规则可以阻止它。如果你真的想这样做,你可以,但你必须确保它们的声明空间不重叠。你可以通过引入额外的大括号来做到这一点:

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

因为现在没有一个空间同时声明"index"意味着两种不同的东西。(很明显,最外层的局部声明空间是一个"索引"表示两种不同的东西的空间,但索引不是在外层声明空间中声明的。)

"for"answers"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) { ... }
    }
}

同样,"不可见"大括号使两个局部变量声明在文本上分离。

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

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

概括一下,两个索引都在同一范围内,其中一个只是在不同的范围内访问。