作为一个.NET程序员有必要对命名空间和程序集有明确的认识,下文很好解释了这两者的关系,感谢作者!
本文转自: 原作者:NetLYF
如果说命名空间是类库的逻辑组织形式,那么程序集就是类库的物理组织形式。只有同时指定类型所在的命名空间及实现该类型的程序集,才能完全限定该类型。《精通.NET核心技术--原理与架构》 程序集和命名空间不存在必然联系,一个程序集可以包含多个命名空间,同一个命名空间也可以分放在几个程序集。
程序集是应用程序的部署单元。.NET应用程序包含一个或多个程序集。通常扩展名是EXE或DLL 的.NET可执行程序称为程序集。.NET程序集包含元数据,这些元数据描述了程序集中定义的所有类型及其成员的信息,即方法、属性、事件和字段。
在使用共享程序集时,几个应用程序都使用同一个程序集,且与它有一定的依赖关系。共享程序集减少了磁盘和内存空间的需求。使用共享程序集时,要遵循许多规则。共享程序集必须有一个版本号和一个唯一的名称,通常它安装在全局程序集缓存(globd assembly cache,GAC,中。GAC允许共享系统上同一个程序集的不同版本。
在一个程序集中可以有不同的名称空间,同一个名称空间也可以分布在多个程序集上。名称空间只是类型名的一种扩展,它属于类型名的范畴。
还可以这样理解:命名空间就是一个程序集内相关类型的一个分组。举例来讲,System.IO命名空间包含了有关文件I/O的类型,System.Data命名空间定义了基本的数据库类型,等等。需要特别指出的是,一个程序集(比如mscorlib.dll)可以包含任意个命名空间,每个命名空间又可以包含多种类型。
更好的理解程序集和命名空间的关系,可以打开VS里的对象浏览器,可以看到大量的程序集,程序集里又包含了很多不同名的命名空间,同时可以看到一个现象:不同的程序集又包含了同名的命名空间。
===========================================
命名空间与装配件的关系
很多人对这个概念可能还是很不清晰,对于合格的.Net程序员,有必要对这点进行澄清。 装配件是.Net应用程序执行的最小单位,编译出来的.dll、.exe都是装配件。 装配件和命名空间的关系不是一一对应,也不互相包含,一个装配件里面可以有多个命名空间,一个命名空间也可以在多个装配件中存在,这样说可能有点模糊,举个例子:装配件A: namespace N1 { public class AC1 {…} public class AC2 {…} } namespace N2 { public class AC3 {…} public class AC4 {…} }
装配件B:
namespace N1 { public class BC1 {…} public class BC2 {…} } namespace N2 { public class BC3 {…} public class BC4 {…} }
这两个装配件中都有N1和N2两个命名空间,而且各声明了两个类,这样是完全可以的,然后我们在一个应用程序中引用装配件A,那么在这个应用程序中,我们能看到N1下面的类为AC1和AC2,N2下面的类为AC3和AC4。
接着我们去掉对A的引用,加上对B的引用,那么我们在这个应用程序下能看到的N1下面的类变成了BC1和BC2,N2下面也一样。 如果我们同时引用这两个装配件,那么N1下面我们就能看到四个类:AC1、AC2、BC1和BC2。
到这里,我们可以清楚一个概念了,命名空间只是说明一个类型是那个族的,比如有人是汉族、有人是回族;而装配件表明一个类型住在哪里,比如有人住在北京、有人住在上海;那么北京有汉族人,也有回族人,上海有汉族人,也有回族人,这是不矛盾的。
命名空间和程序集的关系: 1. 从属于一个命名空间的各个类型可能在不同的程序集中实现。例如:system.IO.FileStream类型是在MSCorlib.dll 程序集中实现的,而System.IO.FileSystemWatcher类型是在System.dll 程序集中实现的。事实上, .Net framework 甚至根本没有发布一个System.IO.dll程序集。(一个程序集内可能有多个命名空间,同一个命名空间可能存在于不同的程序集中.)2. 在一个程序集中,也可能包含不同命名空间中的类型。例如,System.Int32和System.Text.StringBuilder类型都在MSCorLib.dll程序集中。3. 在.net framework SDk文档中查找一个类型时,文档会明确的指出类型所属的命名空间,以及实现了该类型的程序集。(用一个形象的比喻:一个类型,它有两个身份证,一个是命名空间,一个是程序集)