if语句中的作用域变量

3
我以为如果在不同的作用域中,我可以使用同一个名称声明两个变量:

可能是重复问题:
C# 变量作用域

我认为如果在不同的作用域中,我可以使用相同的名称来声明两个变量:

namespace IfScope
{
    class Demo
    {
        public static void Main()
        {
            bool a = true;

            if ( a )
            {
                int i = 1;
            }
            string i  = "s";
        }
    }
}

编译器说了另外一件事:
$ csc Var.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.

Var.cs(13,20): error CS0136: A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'child' scope to denote something else

这意味着在if语句中声明的i变量可以在外部访问(我的理解是这样的)。

但是,如果我尝试使用它,就会出现以下情况。

$ cat Var.cs
namespace IfScope
{
    class Demo
    {
        public static void Main()
        {
            bool a = true;

            if ( a )
            {
                int i = 1;
            }
            i  = "s";
        }
    }
}

Var.cs(13,14): error CS0103: The name 'i' does not exist in the current context

显然,但这里发生了什么?

6
C# 变量作用域 - Sandeep
简短回答:局部变量在其声明的整个块中都是可见的。也就是说,它的作用域包括其声明之前的块部分。请参阅规范(v 4.0)第3.7节。因此,这些作用域并不是分开的。 - phoog
2个回答

3
C# 要求在首次使用简单名称的所有块中,该名称必须具有相同的含义。规范要求:对于表达式或声明符中给定标识符的每个出现,必须在该出现的本地变量声明空间内,让该标识符作为简单名称的每个其他出现都引用同一实体。这个规则确保了一个名称在给定块、switch块、for、foreach或using语句或匿名函数中的含义总是相同的。从这里可以查看更多信息: 链接

不正确。在使用它的所有块中都是如此。但链接是正确的并提供了正确的示例。 - Jirka Hanika

-1
标识符i仅在if内可见,但其作用域是整个方法。这意味着i所标识的变量在方法开始时就存在了。这是因为此时必须分配内存。无法在运行时决定是否在堆栈上分配内存,因此条件块内的所有变量都会在控制流进入if之前创建,并且该变量将一直存在,直到方法返回。

这不是正确的。你可以有两个单独的 if 块,每个块都声明相同的变量。 - Andrew Barber
如果您在两个if语句中声明变量,编译器实际上会声明一个单独的变量并在两个作用域中使用它。话虽如此,在IL级别上,变量名是无关紧要的。因此理论上编译器可以允许使用相同的名称,但这只会鼓励编写令人困惑的代码。 - Muhammad Hasan Khan
@HasanKhan 你可以使用相同的名称但不同的类型。它们确实是不同的。它们的作用域是 if,这使得这个答案是错误的。 - Andrew Barber
@AndrewBarber 你是对的,如果类型不同,则它们是不同的变量,但作用域确实由编译器强制执行。看一下反汇编代码。作用域并不神奇。所有本地变量都在方法开始时声明。 - Muhammad Hasan Khan
但是它们在整个方法期间确实存在。 - wirate
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接