为什么我不能在 C# 的不同作用域中声明一个同名的变量

本文关键字:变量 一个 声明 作用域 不能 为什么 | 更新日期: 2023-09-27 18:34:22

不确定这是否是因为C#编译器特别挑剔,但我尝试在C#中执行此操作:

public static void Main()
{
    bool result = true; // some dummy value
    if(result)
    {
        int x = 5;
        Console.WriteLine(x);
    }
    int x = 10;
    Console.WriteLine(x);
}

编译器抱怨变量名"x"已被使用:

无法在此作用域中声明名为"x"的局部变量,因为它 会给"x"一个不同的含义,它已经在 "子"范围表示其他东西。

我知道它认为这是一个范围问题,但它为什么这么认为?

如果我在 Java 中重现相同的代码,则没有问题。

为什么我不能在 C# 的不同作用域中声明一个同名的变量

并非每个{}都会开始一个新的作用域。 if 块中声明的整数仍与函数位于同一堆栈上。

来自 MSDN 编译器错误 CS0136

对于给定标识符作为简单名称的每次出现 表达式或声明符,在局部变量声明空间内 (§3.3(紧接着该事件,每隔一次 与表达式或声明符中的简单名称具有相同的标识符 必须引用同一实体。此规则可确保 名称在给定块中始终相同,开关块,for-, foreach- 或 using-语句,或匿名函数。

作为第二个参考,请查看 C# 答案中的变量范围混淆,您可以在其中找到相关信息。

您可以在非重叠中使用相同的变量名称 范围。但是,如果一个范围与另一个范围重叠,则不能拥有 两者中声明的相同变量。这样做的原因是为了防止你 不小心在内部使用了已使用的变量名 范围

> 正如@BlackFrog正确指出的那样,每个{ }都不会开始一个新的范围。 来自 C# 语言规范 §3.3:

• 每个方法声明、索引器声明、运算符声明、实例构造函数声明和匿名函数都会创建一个称为局部变量声明空间的新声明空间。名称通过形式参数(固定参数和参数数组(和类型参数引入到此声明空间中。函数成员或匿名函数的主体(如果有(被视为嵌套在局部变量声明空间中。局部变量声明空间和嵌套局部变量声明空间包含同名元素是错误的。

(强调我的(

我认为如果您

x 的外部声明移到 if 语句上方,为什么会更明显。

public static void Main()
{
    bool result = true; // some dummy value
    int x = 10;
    if(result)
    {
        //references x in parent scope
        x = 5;
        //x is already defined, can't define again
        int x = 5;
        Console.WriteLine(x);
    }
    Console.WriteLine(x);
}

显然,当代码尝试再次声明它时,编译器会将x视为已在 if 语句中定义的变量。