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

Tim*_*ter 9 c# compiler-construction types namespaces compiler-errors

我怀疑这是一个曾经多次被问过的问题,但我还没找到.

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

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

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

namespace ns_1
{
    namespace ns_1_1
    {
        public class Foo { }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是以下不起作用:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

它会抛出编译器错误:

找不到类型或命名空间名称"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
        {
            //... 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Imports System.Data

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

        End Using
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

sta*_*erg 5

不幸的是,这种明显的方式不起作用,但您可以通过别名命名空间来实现所有这些:

using ns_1_1 = ns_1.ns_1_1;

public class Program
{
    public Program()
    {
        var no_foo = new ns_1_1.Foo();
    }
}
Run Code Online (Sandbox Code Playgroud)


Sel*_*enç 4

文档

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

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

  • 谢谢。这似乎回答了我的问题。然而,为什么 C# 编译器不够聪明(或者不想)包含在 `using` 中添加的外部命名空间的命名空间?(也许这是 E. Lippert 的问题)VB.NET 支持它,如我的回答所示。 (2认同)
  • 然后 VB 确实在其他“SqlClient”命名空间中使用新类。它似乎获胜,因为它是完全合格的,而模糊类型只是部分合格的。 (2认同)