为什么在命名空间外引用的类型需要完全限定?

8

给定以下代码片段:

using System;

using Foo = System.Int32;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

如果我在“Foo”类型别名的声明中删除“System.”,则会出现编译器错误。尽管我在文件顶部使用了System命名空间,但编译器无法找到未限定的“Int32”类型。
为什么会这样?

1
不是在命名空间之外的“类型”。它只是在使用别名声明时。class Program { static void Main(String[] args) { Int32 x = 0; } } 在命名空间块之外可以正常工作。 - R. Martinho Fernandes
3个回答

10
这是因为C#规范规定了必须这样做。更具体地说,C#规范的第9.4.1节中写道:
using别名指令编写的顺序没有意义,并且使用别名指令引用的命名空间或类型名的解析不受该使用别名指令本身或立即包含的编译单元或命名空间体中的其他using指令的影响。换句话说,使用别名指令的命名空间或类型名会被解析为如果立即包含的编译单元或命名空间体中没有using指令一样。但是,使用别名指令可能会受到立即包含的编译单元或命名空间体中的extern-alias指令的影响。
由于顺序无关紧要,using System;对使用别名指令没有影响。最重要的部分是:“使用别名指令的命名空间或类型名会被解析为如果立即包含的编译单元或命名空间体中没有using指令一样”。

这也解释了为什么在下一行使用“using Bar = System.Collections.Generic.List<Foo>;”也不起作用。谢谢! - Matt Hamilton
@Matt:不客气。当有疑问时,可以在规范中查找。;) - Reed Copsey

6

由于using语句没有特定的处理顺序。编译器不知道在第二行之前处理第一行。


4
规范(9.3) 表示:

using 指令的作用域只包括其直接所在编译单元或命名空间体中的命名空间成员声明。 using 指令的作用域特别不包括同级 using 指令。 因此,互相影响的 using 指令不会影响彼此,它们的书写顺序也不重要。

将您最后的 using 移到命名空间块内就可以了。
using System;

namespace ConsoleApplication3
{
    using Foo = Int32;

我知道它可以在命名空间块内工作,我只是好奇为什么。这是否在规范中有说明? - Matt Hamilton
1
欢迎引用规范中的语句,@Slaks,但我认为我必须把答案给Reed,因为他首先发布了那段文字。不过还是点个赞! - Matt Hamilton

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