为什么我不能在对象初始化期间使用部分限定的命名空间?

我怀疑这是一个以前被问过多次的问题,但我还没找到。

如果我不经常在文件中使用该类型,或者我using namaspacename文件顶部的using namaspacename添加以便能够编写new ClassName()我通常使用完全限定的命名空间。

但是如果只添加了完整命名空间的一部分呢? 为什么编译器找不到类型并抛出错误?

考虑嵌套命名空间中的以下类:

 namespace ns_1 { namespace ns_1_1 { public class Foo { } } } 

因此,如果我现在想要初始化此类的实例,它可以通过以下方式工作:

 using ns_1.ns_1_1; public class Program { public Program() { // works, fully qualified namespace: var foo = new ns_1.ns_1_1.Foo(); // works, because of using ns_1.ns_1_1: foo = new Foo(); } } 

但是以下不起作用:

 using ns_1; public class Program { public Program() { // doesn't work even if using ns_1 was added var no_foo = new ns_1_1.Foo(); } } 

它会抛出编译器错误:

找不到类型或命名空间名称“ns_1_1”(您是否缺少using指令或程序集引用?)

我假设因为ns_1_1被视为包含另一个类Foo而不是命名空间的类,这是正确的吗?

我还没有找到语言规范,这在哪里有记录? 为什么编译器不够聪明,无法检查是否有类命名空间(-part)?


这是另一个 – 不那么抽象 – 我的意思的例子:

 using System.Data; public class Program { public Program() { using (var con = new SqlClient.SqlConnection("...")) // doesn't work { //... } } } 

编辑 :现在我知道为什么这对我来说似乎很奇怪。 它在VB.NET中没有问题:

 Imports System.Data Public Class Program Public Sub New() Using con = New SqlClient.SqlConnection("...") ' no problem End Using End Sub End Class 

文件说:

创建using指令以使用命名空间中的类型,而无需指定命名空间。 using指令不允许您访问嵌套在指定名称空间中的任何名称空间。

因此, using仅包含在指定命名空间中定义的类型(而不是命名空间)。 要访问嵌套命名空间的类型,您需要using指令显式指定它,就像在第一个示例中一样。

这在3.8命名空间和类型名称的标准中有记录,但它有点令人费解。

它的要点是部分命名空间引用仅在它出现的命名空间中查找,并且每个层向外。 不检查using -directives。

在您的示例中,如果在以下任何位置找到Foo则会找到ns_1_1.Foo

 Program.Program.ns_1_1.Foo Program.ns_1_1.Foo ns_1_1.Foo 

仅当您的当前类是该部分命名空间的一部分时,部分命名空间才有效。 不考虑使用语句通过部分命名空间访问类型。

例如,这将起作用,因为您当前的命名空间是ns_1

 namespace ns_1 { public class Program { public Program() { var no_foo = new ns_1_1.Foo(); } } } 

遗憾的是,这种显而易见的方法无效,但您可以通过别名命名空间来完成所有这些:

 using ns_1_1 = ns_1.ns_1_1; public class Program { public Program() { var no_foo = new ns_1_1.Foo(); } }