命名空间
1.命名空间的概念
命名空间(namespace)是对各种类型的名字进行层次规划的方式,命名空间实际上提供了一种命名机制,同时也是程序进行逻辑组织的方式。
命名空间是一些类型的松散的集合,一般不要求处于同一命名空间的类有明确的相互关系,如包含、继承等。为了方便编程和管理,通常把需要在一起工作的类型放在一个命名空间里。如System命名空间下有各种类和接口,包括System.Console
,System.String
,System.Random
,System.Math
,System.GC
,System.IDisposable
,等等,表明这些类型是与系统核心、语言基础直接相关的。命名空间又是按层次组织的,如System
,System.IO
,System.IO.IsolatedStorage
是三个层次的命名空间。
命名空间的使用并不表明可访问性,即与internal
、protected
并不直接相关。命名空间也不表明目标程序的物理组合方式,一个程序中可以有来自各个命名空间的类,也可以定义多个命名空间。命名空间也不表明源文件的存放方式,即没有必要将同一命名空间下的类的定义放在同一目录下,不过那样最好。
2.命名空间的声明
声明一个命名空间时使用关键字namespace
,声明方式如下:
namespace 名字
{
...
}
命名空间的名字可以是一个标识符,或者由多个用圆点(.)分开的多个标识符,如System.IO
。命名空间声明的主体包括的内容是:各个类型声明(struct
,enum
,class
,interface
,delegate
)及嵌套的命名空间的声明。例如:
namespace N1 // N1
{
class C1 // N1.C1
{
class C2 // N1.C1.C2
{
}
}
namespace N2 // N1.N2
{
class C2 // N1.N2.C2
{
}
}
}
用多个圆点来写名字与嵌套的方式,其含义是相同的。例如:
namespace N1.N2
{
class A{}
class B{}
}
从语义上,它与下面的代码相同
namespace N1
{
namespace N2
{
class A{}
class B{}
}
}
命名空间是开放的,也就是说命名空间是可以合并的。以上命名空间中的两个类可以分开定义:
namespace N1.N2
{
class A{}
}
namespace N1.N2
{
class B{}
}
命名空间的可访问性隐含public
,但是不能显示地用任何修饰符进行修饰。
一个命名空间声明在编译单元(源文件)中作为最高级别的声明时,它成为全局空间的一部分。如果一个类型声明没有在命名空间中,则该类型声明是属于全局命名空间的。
3.命名空间的导入
导入命名空间,使用关键字using,其格式如下:
using 命名空间;
注:using 还可以表示导入一个static
类,如using static System.Console;
。
4.使用别名
当导入命名空间后,可能会发生同名的问题,如using N1
及using N2
后,在命名空间N1和N2中都存在类C,这时只写C会有歧义,解决办法就是使用全名如N1.C
和N2.C
。
另外还有一种办法是使用命名空间或类的别名。例如:
using C1 = N1.C;
using C2 = N2.C;
这样,new N1.C
就可以写成为new C1()
。
using 别名 = 命名空间或类名;
别名的指示符,可以放在一个程序的最前面,也可以放在namespace内,但要放在类型声明及嵌套的命名空间的前面。例如:
namespace N1.N2
{
class A {}
}
namespace N3
{
using A = N1.N2.A;
class B : A {}
}
使用别名不仅有利于解决冲突的作用,还可以用来简化书写,例如:
using CodeIds = System.Xml.Serialization.CodeIdentifiers;