命名空間是一個域,這在個域中所有的類型名字必須是唯一的,不同的類型分組歸入到層次化的命名空間,
命名空間的好處是:1、避免名字沖突,2、便於查找類型名字。
如:System.secruity.Cryptogtaphy.
下面介紹namespace 關鍵字的使用。
namespace test
{
class class0
{
int i;
public class0()
{
}
}
}
using關鍵字使用
,訪問一個命名空間的內容可以通過完全限定名。如:test.class0來訪問。但是每次這樣在程序寫很麻煩。你可以使用using指令來引用類型。
命名空間的都是引用類型的。所以在程序的開頭你可以先引用命名空間。就像你使用VS編譯軟件時,每個系統生成的Console中都有
using system;
using system.drawing;
using system.threading ;
之后就可以很方面使用你引用命名空間的類型了。注意using的使用,后面的還要對此做介紹。
全局命名空間
全局命名空間有兩部分組成:
1、所有的頂級命名空間;
2、所有沒有在任何命名空間中聲明的類型;
例如:前面的例子的全局命名空間中聲明了test類型(屬於第一種情況。)
例如:class outer{}//屬於第二種情況;
namespace test1{}是全局命名。
命名空間的規則
名字作用域
所有出現的外部命名空間中的名字都隱式地被引入到內部的命名空間中。在這個例子中middle 和class1被隱式的引入到inner中;
namespace Outer
{
namespace Middle
{
class Class1{}
namespace inner
{
class class2:class1{}
}
}
}
在這個例子中:如下:
namespace test{
namespace Common{
class class1{}
}
namespace Managerreporting{
class class2:Common.class1{}
}
}
可以看到一個test命名空間中包含兩個不交的命名空間。要想引用另外一個,必須使用部分限定名。你可以看出他和上面的例子的區別嗎?
名字屏蔽
內部命名空間的名字會屏蔽外部空間相同的名字。
例如;namespace Outer{
namespace Middle{
class class1{}
class class2{}
}
namespace Inner{
class class1{
class2 cInner;
Middle.class2 couter;
}
class class2{}
}
}
在這個例子中。在OUter命名空間聲明了兩個命名空間,在Inner命名空間中,CInner引用的是Inner.class2的類型。COUter引用的是Middle.class2類型。一個大括號表示程序運行結束時,釋放里面的臨時變量。屏蔽功能僅僅是使用簡單的名字引用某個類型有影響。如果想引用Middle命名空間的class2 的類型。你可以鄉引用couter一樣。用部分限定名或完全限定名。你必須知道屏蔽對於運行時語義並沒有什么影響。(因為編譯器在解析命名空間規則時,總是將名字轉化為完全限定名。編譯后生成的IL語言不會包括無限定的或部分限定名。
重復命名空間
可以重復的聲明一個命名空間,只要命名空間的類型名字沒有沖突;
namespace outer.middle.inner{
class class1{}
}
namespace outer.middle.inner{
class class2{}
}
個人認為可以想下函數的重載。
甚至可以把這個例子分成兩個源文件這樣就可以將每一個類編譯進不同的匯編代碼中;
源文件#1
namespace outer.middle.inner{
class class1{} }
源文件#2
namespace outer.middle.inner{
class class2{}
}
嵌套指令Using
可以在一個命名空間中嵌套using指令。這樣可using指令的作用域限定在命名空間的聲明中。
namespace N1{
class class1{}
}
namespace N2{
using N1;
class class2:class1{}
}//compile true;
namespace N3{
class class3:class1{}
}//compile error
注意說明下這樣的寫,在VS中是無法通過的,還記得前面說的嗎?要想引用層次中的類型,必須加上部分或者完全限定名嗎?
類型別名和命名空間
引入命名空間可能導致類型名沖突,與其說引入命名空間的全部,不如僅選擇要使用的類型引人,給每個要使用的一個別名。
using p=system。reflection
class program{p f;}
但是我們完全沒有必要這樣做。因為我們可以把它們變成全局的引用。就鄉你打開vs時,生成的console一樣。
高級命名空間特性
Extern
外部命名空間允許相同的名字出現。只要包含的類型不同就可以。這種情況最容易發生在來自不同的文件中。
庫#1:
namespace Widgets{
public class Widget{}
}
庫#2:
namespace Widgets{
public class Widget{}
}
程序:
using Widgets;
namespace test{
static void Main()
{
Widget w=new Widget();
}//compile errror;
}
這個程序不正確的,是因為Widget是不確定的。
解決這個問題就是引用完全限定名。
csc /r:W1=WIdgets1.dll /rW2=Widgets2.dll application.cs
或者使用extern alias W1;extern alias W2;
命名空間別名限定
前面提到,內層命名空間的名字會屏蔽外層命名空間的名字。然而。有時候即使使用完全限定類型也不能解決這個沖突。如下:
namespace N{
class A{
public class B{}
static void Main()
{
new A.B();
}
}
}
namespace A{
class B{}
}
這個在運行的是嵌套的B。注意在VS中同一個文件中不可包含同樣的命名空間和類型。但在不同文件可能出現。
有兩種辦法解決可能出現的命名空間沖突問題:
1、使用上面講的使用別名進行。
2、global命名空間----所有的命名空間的根。
namespace test{
static void Main()
{
system.Console.WriteLine(new A.B());
System.Console.WriteLine(new global::A.B());
}
}
別名限定:
external alias W1;
external alias W2;
namespace test{
static void Main()
{
W1.Widgets.Widget w1=new W1.Widgets.Widget();
W2.Widgets.Widget w2=new W2.Widgets.Widget();
}
}
namespace 的內容就講完了,如有什么錯誤還請指正。
from: https://www.cnblogs.com/fandong90/p/4160207.html