【问题标题】:C# scope questionC# 范围问题
【发布时间】:2010-07-30 15:02:16
【问题描述】:

考虑以下代码示例:

                         // line #
{                        // 1
                         // 2
    {                    // 3
        double test = 0; // 4
    }                    // 5
                         // 6  
    double test = 0;     // 7
}                        // 8 

这给出了错误

不能在此范围内声明名为“test”的局部变量,因为它会给“test”赋予不同的含义,而“test”已在“子”范围中用于表示其他内容

但我不明白为什么?外部 test 变量从第 7 行开始,而不是在第 2 行,那么在第 4 行声明第二个变量 test 并在第 5 行结束的问题在哪里?

【问题讨论】:

标签: c# scope


【解决方案1】:

变量的范围在它们声明的中,无论它们在哪一行。

阅读 C# 语言规范中的 scopes

来自规范:

在局部变量声明 (Section 8.5.1) 中声明的局部变量的范围是发生声明的块。

还有:

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

【讨论】:

  • 感谢 Oded / Robert 的解释和链接!顺便说一句,这是来自链接页面msdn.microsoft.com/en-us/library/aa691132%28VS.71%29.aspx 的相关引用:“范围可以嵌套,内部范围可以从外部范围重新声明名称的含义。(但是,这并没有消除第 3.3 节施加的限制,即在嵌套块中,不能声明与封闭块中的局部变量同名的局部变量。)"
  • @stefan.at.wpf - 是的。已更新答案以包含此信息。
【解决方案2】:

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

Lambda variable scope

C# going nuts when I declare variables with the same name as the ones in a lambda

C# variable scoping: 'x' cannot be declared in this scope because it would give a different meaning to 'x'

Variable scope confusion in C#

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

例如:

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# 中。

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

http://blogs.msdn.com/b/ericlippert/archive/tags/simple+names/

【讨论】:

  • 非常感谢您的详细回答!
【解决方案3】:

+1,我同意你的观点,但这不是规范的编写方式。我敢肯定,它使编写编译器更容易。另外,我认为最好不要这样做以使代码更易于理解。

【讨论】:

  • 谢谢tster,我也猜这是主要原因,是的,做某事真的没用。就像在我的示例中一样(只是切换块的顺序......),只是一开始不明白为什么;-)
  • 向您保证它确实不会使编写编译器更容易。编译器中实现此规则的代码是我见过的最复杂、最令人困惑的代码。这段代码中有很多个你永远不会遇到的错误,因为它们都是极其晦涩的极端情况。这个特性的原因是因为它可以防止用户代码中的错误,而不是因为它使我的工作更容易。这让我的工作变得相当困难。
  • @Eric Lippert,感谢专家的证词。
猜你喜欢
  • 2011-01-08
  • 2010-10-11
  • 2016-06-21
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
相关资源
最近更新 更多