使用指示符的目的是為了方便使用其它的名字空間中定義的名字空間和類型。名字空間的指示符有兩種:別名使用指示符(using-alias-directive)和名字空間使用指示符(using-namespace-directive)。
16.3.1 別名使用指示符
C#支持使用別名。別名使用指示符定義一個別名,以後就可以使用這個別名來代替一個類型。這在兩個庫的名字可能發生沖突的情況下非常有用。別名還可以避免使用冗長的名字空間。如下面的代碼定義了MessageSource作為類WelcomeMessage的別名:
using MessageSource=MyProgram.CSharp.FirstApp.WelcomeMessage;
別名使用指示符為我們提供了一個標識符,在整個編譯單元或是在名字空間主體之中,這個標識符作為名字空間或類型的別名。別名使用指示符的語法格式為:
using identifier=namespace-or-type-name;
可以在成員聲明中包含別名使用指示符,這個別名可以用來指代名字空間,也可以用來指代類型,例如:
namespace N1.N2
{
class A{}
}
namespace N3
{
using A=N1.N2.A;
class B:A{}
}
那麼在名字空間N3的成員聲明中,A作為N1.N2.A的別名,則:
class B:A{}
表示N3.B從類N1.N2.A中繼承。下面例子中的寫法也可以達到同樣的效果:
namespace N3
{
using R=N1.N2;
class B:R.A{}
}
注意別名的標識符不能與同一編譯單元或名字空間中的其它成員同名。例如下面的代碼就是不合法的,因為名字空間N3已經包含了成員A:
namespace N3
{
class A{}
}
namespace N3
{
using A=N1.N2.A; //錯誤,A已經存在
}
在用到別名使用指示符時,其中的別名只是在特定的編譯單元或名字空間中有效。看下面的例子:
namespace N3
{
using R=N1.N2;
}
namespace N3
{
class B:R.A{} //錯誤,R在這裡是未知
}
別名R只在包含它的名字空間的主體中有效,在名字空間的第二次聲明中R是未知的。但把別名使用指示符放在編譯單元中,別名對於兩處聲明都是有效的:
using R=N1.N2;
namespace N3
{
class B:R.A{}
}
namespace N3
{
class C:R.A{}
}
16.3.2 名字空間使用指示符
使用名字空間指示符為編譯單元或名字空間主體導入了另一個名字空間的類型,對這些類型的使用無需全名。使用名字空間指示符的語法格式:
using namespace-name;
在編譯單元或名字空間的成員聲明中,名字空間中包含的類型可以被成員直接使用。例如:
namespace N1.N2
{
class A{}
}
namespace N3
{
using N1.N2
class B:A{}
}
一個名字空間使用指示符導入了在給出的名字空間中包含的類型,但沒有引入嵌套的名字空間。見下例:
namespace N1.N2
{
class A{}
}
namespace N3
{
using N1;
class B:N2.A{} //錯誤,N2未知
}
這裡,名字空間使用指示符導入了N1中包含的類型,但沒有導入N1中的嵌套。所以,在類B的聲明中引用N2.A是錯誤的。
和別名使用指示符不同,名字空間使用指示符可以導入在編譯單元或名字空間主體中預定義的類型。
在使用名字空間的時候,如果在編譯單元或名字空間主體中定義的成員與名字空間使用指示符導入的成員名字相同,編譯器將認作是前者。也就是說,編譯單元或名字空間主體中定義的成員覆蓋了名字空間使用指示符導入的同名成員。
namespace N1.N2
{
class A{}
class B{}
}
namespace N3
{
using N1.N2;
class A{}
}
上面的例子中,因為名字空間N3中聲明了成員A,所以A表示的是N3.A,而不是N1.N2.A。
如果在編譯單元或名字空間主體中,通過名字空間使用指示符導入了多個名字空間,而這些名字空間中又包含了同名的類型,對這類名字的使用將會引起混淆。
namespace N1
{
class A{}
}
namespace N2
{
class A{}
}
namespace N3
{
using N1;
using N2;
class B:A{} //錯誤,A有二義性
}
由於名字空間N1和N2都包含了成員A,而名字空間N3又同時導入了N2和N1,那麼在名字空間N3中就不能引用成員A,因為這時編譯器無法判斷指的是N1.A還是N2.A。要解決這個矛盾,我們要麼給成員加上具體的限制,要麼使用名字空間使用指示符表明究竟引用的是哪個成員。如果表示的是N1.A,那麼下面的寫法就是正確的:
namespace N3
{
using N1;
using N2;
using A=N1.A;
class B:A{} //A表示N1.A
}
和別名使用指示符一樣,名字空間使用指示符並沒有在編譯單元或名字空間的聲明中添加新的成員,並且只對它所在的編譯單元或名字空間有作用,對其它的編譯單元和名字空間則沒有影響。
最後要說明的一點是,在同一個編譯單元或名字空間主體中,對名字空間使用指示符沒有順序上的限制,它們之間不會相互影響。