为什么我不能在对象初始化期间使用部分限定的命名空间?
我怀疑这是一个以前被问过多次的问题,但我还没找到。
如果我不经常在文件中使用该类型,或者我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(); } }