技術頻道導航
HTML/CSS
.NET技術
IIS技術
PHP技術
Js/JQuery
Photoshop
Fireworks
服務器技術
操作系統(tǒng)
網(wǎng)站運營

贊助商

分類目錄

贊助商

最新文章

搜索

在C#中為什么這樣訪問嵌套命名空間的類不對?【解決】

作者:admin    時間:2023-4-27 19:54:13    瀏覽:

在C#中,訪問嵌套命名空間的類的時候,你如果是一個新手,或者對C#嵌套命名空間的了解還不夠透徹,那么就有可能出現(xiàn)如本文中的錯誤。

問題

有如下嵌套命名空間代碼:

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

我用如下寫法調(diào)用類foo

using n1;

n2.foo something;

但是這樣寫不對!

那么該如何寫才對呢?

解答一

這是 C# 的規(guī)則,如果你這樣做:

namespace Frobozz
{
    namespace Magic
    {
        class Lamp {}
    }

    class Foo
    {
        Magic.Lamp myLamp; // 合規(guī); 
    }
}

那是合規(guī)的,當MagicFrobozz里時,Magic的意思是Frobozz.Magic。但下面代碼不是:

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

namespace Flathead
{
    using Frobozz;
    class Bar
    {
        Magic.Lamp myLamp; // 不合規(guī)
    }
}

這是不合規(guī)的,僅僅使用Frobozz并不能將Magic帶入范圍。

描述這一點的 C# 規(guī)則在 C# 4 規(guī)范的第 7.6.2 節(jié)中。這是一個非?;靵y的部分;你想要的是靠近末尾的段落:

否則,如果命名空間聲明的 using-namespace-directives 導入的命名空間恰好包含一個名稱為 ... 的類型......

關鍵是它說的是“恰好是一種類型”,而不是“恰好是一種類型或命名空間”。當你在該名稱空間之外時,我們不允許你像這樣“切片”命名空間名稱,因為它可能會造成混淆。正如其他人所說,如果你想做那種事情,請在使用別名(using-alias)指令中完全限定一次,然后使用別名。

使用命名空間別名:

using n2 = n1.n2;

...
n2.foo something;

類名之前應該是一個完整的命名空間(帶有/或嵌套類型的其他類名),截斷的命名空間將不起作用。

解答二

通過設計,命名空間可以幫助你定義范圍。

除非你完全限定它,否則你會得到你所看到的錯誤。

假設你有這樣的代碼:

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

你可以通過兩種方式執(zhí)行此操作。

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# 語言規(guī)范中的第 9.4.2 節(jié)第 4 段明確解釋了此行為:

using-namespace-directive導入給定命名空間中包含的類型,但特別是不導入嵌套的命名空間。

它甚至繼續(xù)舉了一個與你自己的非常相似的例子。

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; // 這是合規(guī)的
    }
  }
}

這將編譯,因為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();
    }
}

但是,這不能創(chuàng)建命名空間的聯(lián)合,如果你有:

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有歧義義,因為它可以在這個上下文中引用兩個類符號。我試圖將命名空間聲明為接口,并使用一個類來實現(xiàn)它們以創(chuàng)建命名空間的聯(lián)合,但是,實現(xiàn)接口不會自動在其中導入嵌套類符號。

相關文章

標簽: CSharp  asp.net  命名空間  
x