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

问题描述 投票:0回答:4

我怀疑这个问题以前已经被问过很多次了,但我还没有找到。

如果我不经常在文件中使用该类型,或者我在文件顶部添加

using namaspacename
以便能够写入
new ClassName()
,我通常会使用完全限定的命名空间。

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

考虑在nested命名空间中使用以下类:

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
而不是命名空间的类,这是正确的吗?

我还没有找到语言规范,它在哪里记录?为什么编译器不够智能来检查是否存在类命名空间(-部分)?


这是另一个不太抽象的例子来说明我的意思:

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
c# types compiler-errors namespaces
4个回答
7
投票

不幸的是,这种明显的方法不起作用,但你可以通过别名命名空间来实现这一切:

using ns_1_1 = ns_1.ns_1_1;

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

4
投票

文档说:

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

因此

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


2
投票

这记录在3.8命名空间和类型名称的标准中,但遵循起来有点复杂。

其要点是,仅在其出现的命名空间以及向外的每一层中查找部分命名空间引用。

using
-未检查指令。

在您的示例中,如果在以下任意位置找到

ns_1_1.Foo
,就会找到
Foo

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

2
投票

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

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

ns_1

namespace ns_1
{
    public class Program
    {
        public Program()
        {
            var no_foo = new ns_1_1.Foo();
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.