C# Can';不要在方法中使用相同的variablename

C# Can';不要在方法中使用相同的variablename,c#,methods,C#,Methods,为什么我不能在方法中使用相同的变量名,例如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 loo

为什么我不能在方法中使用相同的变量名,例如
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)
}
private void Foo()
{
对于(int-index=0;index<10;index++)/“first”-index
{
//毫无疑问,在这里使用“第一”-索引
//(且仅在for循环的范围内)
}
int index=0;/“秒”-索引
//毫无疑问,在这里使用“第二”索引
//(及以下)
}
是因为分配是在编译时进行的吗?但是,为什么编译器不能在幕后调用“第一个”索引来表示索引_1,调用“第二个”索引来表示索引_2呢

如果我有

    private void Foo()
    {
        for (int index = 0; index < 10; index++)
        {
        }
        // the runtime don't know index here
    }
private void Foo()
{
对于(int-index=0;index<10;index++)
{
}
//运行时不知道这里的索引
}

如果运行时不知道for循环下面的索引,为什么我们不能使用另一个具有该名称的变量?

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

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


总而言之,两个索引都在同一个范围内,一个只是在不同的范围内访问。

这些变量的声明空间重叠,即使范围没有重叠。查看Eric Lippert关于该主题的博客:

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

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


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

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

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

继续

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

{
    {
        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;index我不知道官方原因,但一般来说,C#团队查看了常见的bug来源,并将它们在语言中定为非法。另一个例子:switch没有fallthru..case语句,因为缺少中断是允许这种情况的语言上的常见错误。关闭但不完全关闭。实际上范围覆盖了在本例中,声明空间和范围的大小是相同的(尽管有时声明空间和范围的大小不同)请记住,C中的局部范围是整个块,不像C++中的那样。在这个程序中,违反了C的两个规则。同一个名称的两个变量在嵌套的局部变量声明空间中声明,并且相同的简单名称用于指嵌套块中的两个不同的事物。
{
    {
        int index = 0; 
        while(index <= 10) { ... }
    }
    {
        int index = 0; 
        while(index <= 10) { ... }
    }
}