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

贊助商

分類目錄

贊助商

最新文章

搜索

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

作者:admin    時(shí)間:2023-4-27 19:54:13    瀏覽:

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

問題

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

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

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

using n1;

n2.foo something;

但是這樣寫不對(duì)!

那么該如何寫才對(duì)呢?

解答一

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

namespace Frobozz
{
    namespace Magic
    {
        class Lamp {}
    }

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

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

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

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

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

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

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

關(guān)鍵是它說的是“恰好是一種類型”,而不是“恰好是一種類型或命名空間”。當(dāng)你在該名稱空間之外時(shí),我們不允許你像這樣“切片”命名空間名稱,因?yàn)樗赡軙?huì)造成混淆。正如其他人所說,如果你想做那種事情,請(qǐng)?jiān)谑褂脛e名(using-alias)指令中完全限定一次,然后使用別名。

使用命名空間別名:

using n2 = n1.n2;

...
n2.foo something;

類名之前應(yīng)該是一個(gè)完整的命名空間(帶有/或嵌套類型的其他類名),截?cái)嗟拿臻g將不起作用。

解答二

通過設(shè)計(jì),命名空間可以幫助你定義范圍。

除非你完全限定它,否則你會(huì)得到你所看到的錯(cuò)誤。

假設(shè)你有這樣的代碼:

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

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

1、使用完全限定名稱

代碼:

namespace n3
{
    using n1.n2;

    class TestClass
    {
        private Foo something;
    }
}

2、用一個(gè)別名

代碼:

namespace n3
{
    using n2 = n1.n2;

    class TestClass
    {
        private n2.Foo something;
    }
}

解答三

C# 語言規(guī)范中的第 9.4.2 節(jié)第 4 段明確解釋了此行為:

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

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

namespace N1.N2
{
    class A {}
}
namespace N3
{
    using N1;
    class B: N2.A {}        // 錯(cuò)誤, N2未知
}

然而,如果你把代碼改為這樣:

namespace n1
{
  public class Example
  {
    public static void Main()
    {
      n2.Foo a; // 這是合規(guī)的
    }
  }
}

這將編譯,因?yàn)?strong>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();
    }
}

編譯器會(huì)認(rèn)為NNS有歧義義,因?yàn)樗梢栽谶@個(gè)上下文中引用兩個(gè)類符號(hào)。我試圖將命名空間聲明為接口,并使用一個(gè)類來實(shí)現(xiàn)它們以創(chuàng)建命名空間的聯(lián)合,但是,實(shí)現(xiàn)接口不會(huì)自動(dòng)在其中導(dǎo)入嵌套類符號(hào)。

相關(guān)文章

標(biāo)簽: CSharp  asp.net  命名空間  
x
  • 站長(zhǎng)推薦
/* 左側(cè)顯示文章內(nèi)容目錄 */