技术频道导航
HTML/CSS
.NET技术
IIS技术
PHP技术
Js/JQuery
Photoshop
Fireworks
服务器技术
操作系统
网站运营

赞助商

分类目录

赞助商

最新文章

搜索

在C#中为什么这样访问嵌套命名空间的类不对?【解决】

作者:admin    时间:2023-4-27 19:54:13    浏览:

在C#中,访问嵌套命名空间的类的时候,你如果是一个新手,或者对C#嵌套命名空间的了解还不够透彻,那么就有可能出现如本文中的错误。

问题

有如下嵌套命名空间代码:

namespace n1
{
    namespace n2
    {
        class foo{}
    }
}

我用如下写法调用类foo

using n1;

n2.foo something;

但是这样写不对!

那么该如何写才对呢?

解答一

这是 C# 的规则,如果你这样做:

namespace Frobozz
{
    namespace Magic
    {
        class Lamp {}
    }

    class Foo
    {
        Magic.Lamp myLamp; // 合规; 
    }
}

那是合规的,当MagicFrobozz里时,Magic的意思是Frobozz.Magic。但下面代码不是:

namespace Frobozz
{
    namespace Magic
    {
        class Lamp {}
    }
}

namespace Flathead
{
    using Frobozz;
    class Bar
    {
        Magic.Lamp myLamp; // 不合规
    }
}

这是不合规的,仅仅使用Frobozz并不能将Magic带入范围。

描述这一点的 C# 规则在 C# 4 规范的第 7.6.2 节中。这是一个非常混乱的部分;你想要的是靠近末尾的段落:

否则,如果命名空间声明的 using-namespace-directives 导入的命名空间恰好包含一个名称为 ... 的类型......

关键是它说的是“恰好是一种类型”,而不是“恰好是一种类型或命名空间”。当你在该名称空间之外时,我们不允许你像这样“切片”命名空间名称,因为它可能会造成混淆。正如其他人所说,如果你想做那种事情,请在使用别名(using-alias)指令中完全限定一次,然后使用别名。

使用命名空间别名:

using n2 = n1.n2;

...
n2.foo something;

类名之前应该是一个完整的命名空间(带有/或嵌套类型的其他类名),截断的命名空间将不起作用。

解答二

通过设计,命名空间可以帮助你定义范围。

除非你完全限定它,否则你会得到你所看到的错误。

假设你有这样的代码:

namespace n1
{
    namespace n2
    {
        class Foo { }
    }
}

你可以通过两种方式执行此操作。

1、使用完全限定名称

代码:

namespace n3
{
    using n1.n2;

    class TestClass
    {
        private Foo something;
    }
}

2、用一个别名

代码:

namespace n3
{
    using n2 = n1.n2;

    class TestClass
    {
        private n2.Foo something;
    }
}

解答三

C# 语言规范中的第 9.4.2 节第 4 段明确解释了此行为:

using-namespace-directive导入给定命名空间中包含的类型,但特别是不导入嵌套的命名空间。

它甚至继续举了一个与你自己的非常相似的例子。

namespace N1.N2
{
    class A {}
}
namespace N3
{
    using N1;
    class B: N2.A {}        // 错误, N2未知
}

然而,如果你把代码改为这样:

namespace n1
{
  public class Example
  {
    public static void Main()
    {
      n2.Foo a; // 这是合规的
    }
  }
}

这将编译,因为n2是可访问的,它是从原型命名空间块中引用的。

解答四

一种方法是将嵌套的命名空间声明为类。

比如你有如下代码:

namespace NS1
{
    public class NNS1
    {
        public class C { }
    }
}
namespace NS2
{
    public class NNS2
    {
        public class C { }
    }
}

然后通过以下方式使用你的命名空间:

using NS1;
using NS2;

class C
{
    public C()
    {
        var c1 = new NNS1.C();
        var c2 = new NNS2.C();
    }
}

但是,这不能创建命名空间的联合,如果你有:

namespace NS1
{
    public class NNS
    {
        public class C1 { }
    }
}
namespace NS2
{
    public class NNS
    {
        public class C2 { }
    }
}

using NS1;
using NS2;

class C
{
    public C()
    {
        var c1 = new NNS.C1();
        var c2 = new NNS.C2();
    }
}

编译器会认为NNS有歧义义,因为它可以在这个上下文中引用两个类符号。我试图将命名空间声明为接口,并使用一个类来实现它们以创建命名空间的联合,但是,实现接口不会自动在其中导入嵌套类符号。

相关文章

标签: CSharp  asp.net  命名空间  
x
  • 站长推荐
/* 左侧显示文章内容目录 */