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

时间:2014-07-31 14:47:16

标签: c# types compiler-construction compiler-errors namespaces

我怀疑这个问题曾经多次被问过,但我还没找到。

如果我不经常在文件中使用该类型,或者我在文件顶部添加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

4 个答案:

答案 0 :(得分:3)

documentation说:

  

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

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

答案 1 :(得分:2)

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

using ns_1_1 = ns_1.ns_1_1;

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

答案 2 :(得分:1)

3.8 Namespace and Type Names中的标准对此进行了记录,但有点令人费解。

部分命名空间引用仅在发生它的命名空间中查找,并且每个层向外查找。 using - 未检查指令。

在您的示例中,如果在任何地方找到ns_1_1.Foo,则会找到Foo

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

答案 3 :(得分:1)

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

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

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