微软的Visual
Studio .NET给Visual Studio开发者带来了许多新概念,其中包括微软中介语言(MSIL)的运行时编译、垃圾收集、公共语言运行时(CLR)等,同时也包括了也许最令人产生错误理解的两个术语:名称空间(namespace)和装配(assemblies)。为了帮助你更好地了解.NET环境,我们将在这篇文章里具体讨论名称空间和装配,同时澄清两个概念之间的关系。
乍看之下,名称空间就好象C++语言中的include指示符或者项目中附加的VB模块。但是,在Visual Studio .NET中,随C#的using指示符和VB Import语句而出现的名称空间和装配概念已经超出了包含预定义头文件的含义。它们代表了一种同外部代码库交互的方式,而这些代码库对微软开发者而言可能完全是一种全新的感觉。
简单地说,一个名称空间不过是一组相互联系的类。正是把关联的类放在同一容器内才能把这些类同其他同名的类区分开来。熟悉Java语言的程序员就会把名称空间当作他们耳熟能详的Java包。名称空间是一种逻辑上的而非物理意义的分组。物理分组是由装配完成的,它在大多数情况下就直接等同于动态连接库、COM对象或OCX模块。
.NET CLR由多种名称空间所组成,范围涵盖了众多的装配。例如,ADO.NET就是位于System.Data名称空间中的类集合。而ASP.NET则是位于System.Web名称空间中的类集合。
图A所示为组成.NET CLR的名称空间中各种类的分组情况。每一块都代表了单独的一个名称空间。在CLR上,每一名称空间所包含的类和结构都代表了同一主题的开发领域。进一步说,名称空间系统也是层次型的,它允许在父名称空间内部实现功能划分。比方说,System名称空间就是其他所有名称空间的根。
图A
有必要指出,名称空间不总是等同于某种功能库。例如传统型的DLL、COM对象或OCX等。在.NET环境内,名称空间只代表了代码的逻辑组织而并非必然确定代码的物理位置。
Visual Studio .NET中的代码是通过装配实现物理组织和结构化的。所谓的装配几乎就指的是DLL,尽管一个装配通常由一个以上的DLL或EXE组成。但事实上,你却很难找到对术语DLL的引用,看起来似乎微软特别热切于把技术术语尽快地放进计算机科学的编年史。已经具备Java编程技能的人则会认出装配就是jar文件。
装配就是包含.NET可执行代码的二进制文件,这些可执行代码则根据MSIL编译而成。装配和名称空间之间的关系可能会叫人觉得犯糊涂,由于装配能包含一个或者一个以上的名称空间,而一个名称空间又可以被一个以上的装配所包含。所以每个装配都可能配置根名称空间。如果根名称空间值留空白,那么根名称空间值默认为装配名。你可以通过项目属性对话框设置根名称空间,如图B所示。
图B
装配相比传统的DLL、OCX或COM文件提供了更多的优点。下列只是装配设计所能提供的部分优点之一:
假定你现在有个类叫Manager,它驻留在Emploee名称空间内,而后者又驻留在Company.dll装配内。为了使用这个类,你必须首先用Solution Explorer的References一节引用该装配。对Java程序员来说,这就好比给jar文件设置类路径。通过这一操作即可告诉开发项目在哪儿能找到物理文件。一旦找到引用,你即可采用imports Employee(VB)或Employee(C#)指示符使用名称空间。Imports可以针对文件或者项目采用。当你在自己的项目中的大多数文件中使用名称空间时你应该采用后者。例如,你的很多文件都可能会用到System.data名称空间,所以不妨在项目级别导入这一名称空间。设置项目级导入采用项目属性对话框进行配置即可。
初学者可能很难弄清楚名称空间和装配之间的关系,你只需要记住:名称空间代表你的对象模型的逻辑视图,而装配则代表物理部署。名称空间提供了应对对象识别和定位等困难问题的层次性解决办法。它们消除了其他对象引用形式所存储的不确定性,同时凭借关联对象的集中驻留而简化了连接库的设计。
通过装配管理的运用,你可以很容易地实现版本控制、运行安全,同时还解决了传统意义上不得不由手工施行的连接库部署所引发的诸多问题。而且,SxS装配版本实现了装载模块的热交换,更不用提其部署的大大简化了(欢迎xCopy归来!我们太想念它了)。在装配 /名称空间提供如此之多优点的同时,你或许会感慨,自己竟然能从之前昏暗的编程生活中活下来简直是不可思议!