为什么可以成功编译另一个类中的“非法”声明变量?

时间:2019-01-09 03:28:32

标签: c#

我创建了一个如下所示的c#测试类,我打算测试如果在范围内外两次创建一个变量会发生什么。但是令我惊讶的是,它运行并输出值“ inside”。

这是一种非法声明多个变量的非法方法,如果我将此代码片段写入Main()方法,则会相应地发生编译器错误。但是它如何在单独的类中工作呢?那我们怎样才能避免犯这样的错误呢?

    class Program
    {
        static void Main(string[] args)
        {                
            Test tst = new Test();
            tst.ScopeAlert();
            Console.ReadLine();
        }
    }

    public class Test
    {
        string scope = "outside";
        public void ScopeAlert()        
        {
            string scope = "inside";

            Console.WriteLine(scope);
        }
    }

2 个答案:

答案 0 :(得分:9)

首先,尽管您正确地认为它们是范围,但在这种特定情况下使用的更好的行话是声明空间。有细微的差别。声明空间是一个代码区域,在其中不能声明两个名称相同的名称(重载方法除外)。 范围是文本区域,可以在其中使用特定名称而无限制。它们密切相关,但不是一回事。

C#的规则是,用于类和局部变量的声明空间不同,并且允许在两者中声明相同的名称。但是,针对本地人的嵌套声明空间不允许内部空间中的本地人遮蔽外部空间中的本地人

您的示例是合法的,因为声明空间并不都是局部的。

如果我们有局部空间:

.

这是合法的,因为它们不重叠。但是

void M()
{
  { int j = 1; }
  { int j = 2; }
}

是非法的,因为空格确实重叠。

有关更多详细信息,请咨询C#规范。

答案 1 :(得分:1)

在C#中,您所拥有的一切都很好,并且被允许。如果您需要访问

string scope = "outside";

然后需要使用this.scope。有关变量privatepublicinternalprotectedprotected internal等变量的可访问性级别的更多信息,请参见此处:

In C#, what is the difference between public, private, protected, and having no access modifier?

还有一种方法:

public void ScopeAlert()        {
    string scope = "inside";

    Console.WriteLine(scope);
}

可以在方法中的任何位置访问用值“ inside”定义的变量。但是,以下操作无效:

public void ScopeAlert()        {
    while(true) 
    {
        string scope = "inside";
    }

    Console.WriteLine(scope);  // will give an error as scope is limited to {}.
}