c# - 为什么 C# 不允许我在不同的范围内使用相同的变量名?

标签 c# .net compiler-construction

例如:

if ( this.IsValid )
{
    Matrix matrix = new Matrix();
}

Matrix matrix = new Matrix();

编译器警告我说:

“不能在此范围内声明名为‘matrix’的局部变量,因为它会给‘matrix’赋予不同的含义,后者已经在‘ child 的范围来表示别的东西。

这些变量不是在不同的范围内,所以我无论如何都无法从 if 语句外部访问第一个 matrix 吗?

最佳答案

更新:以下 2011 年的答案对于早期版本的 C# 是正确的;在更新的版本中,描述答案的规则已从 C# 中删除。设计团队确定,即使我大大改进了错误消息以更清楚地诊断问题,该规则在开发人员中引起的困惑导致了像这样的问题,而不是被阻止的错误程序所保证的。


到目前为止给出的答案非常困惑。对问题的正确分析从阅读错误信息开始。错误消息告诉您实际上出了什么问题:

"A local variable named 'matrix' cannot be declared in this scope because it would give a different meaning to 'matrix', which is already used in a 'child' scope to denote something else.

仔细阅读。它准确地告诉您违反了 C# 的哪条规则,即不允许您在同一范围内使用相同的名称来指代两个不同的事物。 (实际上,错误消息有点错误;它应该在它说“范围”的地方说“局部变量声明空间”,但那太罗嗦了。)

此规则记录在 C# 4.0 规范的第 7.6.2.1 节:简单名称, block 中的不变含义。

(在重叠的声明空间中有两个同名的局部变量也是非法的。编译器也可能会报告该错误,但在这种情况下它会报告更一般的错误。 )

Aren't these variables in different scopes, so I wouldn't be able to access the first matrix from outside the if statement anyway?

是的。该陈述正确无关紧要。这里的错误是在同一局部变量声明空间中使用了相同的简单名称来指代两个不同的事物

考虑这个场景:

class C 
{
    int x;
    void M()
    {
        x = 10; // means "this.x"
        for(whatever)
        {
            int x = whatever;
        }
    }
 }

同样的交易。这里的错误是在外部声明空间中使用简单名称“x”来引用 this.x,并在内部声明空间中使用以表示“局部变量”。在同一个声明空间中使用相同的简单名称来指代两个不同的事物——记住,内部声明空间是外部声明空间的部分——两者都令人困惑并且危险,因此是非法的。

由于显而易见的原因,它令人困惑;人们有一个合理的期望,即名称在其首次使用的整个声明空间中的任何地方都具有相同的含义。这很危险,因为小的代码编辑很容易改变含义:

class C 
{
    int x;
    void M()
    {
        int x;
        x = 10; // no longer means "this.x"
        for(whatever)
        {
            x = whatever;
        }
    }
 }

如果首次使用简单名称的声明空间不重叠,那么简单名称引用不同事物是合法的:

class C 
{
    int x;
    void M()
    {
        {
            x = 10; // means "this.x"
        }
        for(whatever)
        {
            int x = whatever; // Legal; now the 
        }
    }
 }

有关油炸食品的更多信息和有趣的故事,请参阅

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

关于c# - 为什么 C# 不允许我在不同的范围内使用相同的变量名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4649947/

相关文章:

compiler-construction - 创建编译器 : Learn OCaml or Stick With Java/C/C++

c# - Windows Phone 导航到同一页面的新实例

c# - 从 JToken 中获取可能不存在的值(value)(最佳实践)

.net - Windows 10 拖放

c# - 在 visual studio 2010 中添加安装项目的快捷方式

c++ - 如何找到第一个集合?

c# - 用什么?委托(delegate)、事件或 Func<T>?

c# - 转换十进制?加倍?

c# - GC 何时可以收集挂接到事件的 Lambda?

compiler-construction - ANTLR树有必要吗?