C#范围问题

C#范围问题,c#,scope,C#,Scope,考虑以下代码示例: // line # { // 1 // 2 { // 3 double test = 0; // 4 } // 5 // 6 double test = 0;

考虑以下代码示例:

                         // line #
{                        // 1
                         // 2
    {                    // 3
        double test = 0; // 4
    }                    // 5
                         // 6  
    double test = 0;     // 7
}                        // 8 
这就产生了错误

无法在此作用域中声明名为“test”的局部变量,因为它将赋予“test”不同的含义,而“test”已在“child”作用域中用于表示其他内容


但我不明白为什么?外部测试变量从第7行开始,而不是从第2行开始,因此在第4行声明第二个名为test的变量(作用域结束于第5行)有什么问题呢?

变量的作用域在它们声明的块中,它们在哪一行都不重要

阅读C语言规范中的相关内容

根据规范:

局部变量声明()中声明的局部变量的作用域是发生声明的块

以及:

作用域可以嵌套,内部作用域可以从外部作用域重新声明名称的含义。(但是,这并没有消除第3.3节施加的限制,即在嵌套块中,不可能声明与封闭块中的局部变量同名的局部变量。)


+我同意你的看法,但这不是规范的编写方式。我相信这会使编写编译器更容易。此外,我认为可以说,最好不要这样做,以使代码更容易理解。

这是一个常见问题;另见:

答案是:更仔细地阅读错误消息。错误消息准确地说明了问题所在:不允许在同一块中使用相同的简单名称来表示两个不同的内容

例如:

class C
{
    int x;
    void M()
    {
        int x;
    }
}
完全合法。请注意,外部x的范围与内部x的范围重叠。在两者的作用域中使用相同名称的重叠作用域并不违法

这是不合法的:

class C
{
    int x;
    void M()
    {
        Console.WriteLine(x); // this.x
        {
            int x;
        }
    }
}
同样,两个x重叠的范围是完全合法的。非法的是,在同一个块中使用简单名称x表示两个不同的变量,即在M()的外部块中,其中包含M的内部块

使用相同的简单名称表示同一块中两个不同事物的程序容易混淆,容易出现错误,因此在C#中是非法的

有关更多详细信息,请阅读我的文章:


错误消息几乎说明了一切。语言设计者这样做是为了鼓励人们在一个作用域块中使用不同的变量名,以避免混淆,即使他们可以更严格地编写作用域。因此,子作用域中的变量必须具有唯一的命名。我认为这是.NET(ref)各部分设计中“成功之坑”理念的一个例子。请注意,这是、、的副本,感谢您的解释和链接,Oded/Robert!顺便说一句,这里有链接页面的相关引用:“作用域可以嵌套,内部作用域可以从外部作用域重新声明名称的含义。(但是,这并没有消除第3.3节施加的限制,即在嵌套块内不可能声明与封闭块中的局部变量同名的局部变量。)@stefan.at.wpf-真的。答案已更新以包含这一点信息。谢谢tster,我也猜这是主要原因,是的,在我的示例中(只是切换块的顺序…),只是不理解为什么在第一刻;-)我向您保证这不会使编写编译器变得更容易。编译器中实现此规则的代码是我见过的最毛茸茸、最令人困惑的代码之一。这段代码中有很多你永远不会遇到的bug,因为它们都是非常模糊的情况。这个特性的原因是因为它防止了用户代码中的错误,而不是因为它使我的工作更容易。“这让我的工作更加困难了。”埃里克·利珀特,谢谢你的专家证词。非常感谢你给出的详细答案!