为什么不能在对象初始化期间使用部分限定的命名空间?
本文关键字:命名空间 用部 不能 对象 初始化 为什么 | 更新日期: 2023-09-27 18:15:54
我怀疑这是一个已经问过很多次的问题,但我还没有找到一个。
我通常使用完全限定的命名空间,如果我不经常在文件中使用这种类型,或者我在文件的顶部添加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中工作没有问题。净:
Imports System.Data
Public Class Program
Public Sub New()
Using con = New SqlClient.SqlConnection("...") ' no problem
End Using
End Sub
End Class
这种明显的方式不幸不起作用,但您可以通过别名命名空间来实现这一切:
using ns_1_1 = ns_1.ns_1_1;
public class Program
{
public Program()
{
var no_foo = new ns_1_1.Foo();
}
}
文档说:
创建using指令来使用命名空间中的类型,而不必指定命名空间。 using指令不允许你访问任何嵌套在你指定的命名空间中的命名空间。
所以using
只包括在指定的名称空间中定义的类型(不包括名称空间)。为了访问嵌套命名空间的类型,您需要像在第一个示例中那样使用using
指令显式地指定它。
这在3.8命名空间和类型名称的标准中有记录,但是要遵循它有点复杂。
它的要点是,部分名称空间引用只在它出现的名称空间中查找,并向外每层查找。不检查using
-指令
在您的示例中,如果在
中找到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();
}
}
}