我们都知道using有三个作用:·引入命名空间,创建别名,强制资源清理。这次对using 的“引入命名空间”的作用有了一点小疑问:命名空间和程序集有什么关系?
起因:
在项目中编码时,我遇见了一种情况:在未引用system.web程序集(未添加system.web引用)的情况下,通过using ,引入system.web 命名空间后,在程序中却不能使用system.web命名空间中httpcontext类。
解决方法是:
在项目的“引用”中添加 system.web 引用,引用程序集httpcontext,httpcontext类就可以使用了。
问题倒是解决了,但是为什么要这样做呢?这就要了解一下命名空间和程序集到底是什么了。
关于命名空间:
百度一下:
如同名字一样的意思,NameSpace(名字空间),之所以出来这样一个东西,是因为人类可用的单词数太少,并且不同的人写的程序不可能所有的变量都没有重名现象,对于库来说,这个问题尤其严重,如果两个人写的库文件中出现同名的变量或函数(不可避免),使用起来就有问题了。为了解决这个问题,引入了名字空间这个概念,通过使用 namespace xxx;你所使用的库函数或变量就是在该名字空间中定义的,这样一来就不会引起不必要的冲突了。
微软的类库是把作用相关的类放到同一个命名空间中,避免产生类名冲突。命名空间在名称上对类库中类进行了区分。
程序集:
如果说命名空间是类库的逻辑组织形式,那么程序集就是类库的物理组织形式。只有同时指定类型所在的命名空间及实现该类型的程序集,才能完全限定该类型。在我的项目中,正是因为只引入了命名空间,没有引入程序集才导致不能使用system.web中的类。
程序集是应用程序的部署单元,.NET应用程序包含一个或多个程序集。通常扩展名是EXE或DLL 的.NET可执行程序称为程序集。.NET程序集包含元数据,这些元数据描述了程序集中定义的所有类型及其成员的信息,即方法、属性、事件和字段。
两者之间的关系:
我们在编程时,引用了某个程序集,可直接以system.web.httpcontext.courrent的方法调用程序集里面的方法;但如果引用命名空间system.web,可以直接用httpcontext.courrent,来减少代码量。
在编译时,using命令告诉编译器,我这个类里,使用了某个命名空间,不用再写空间的名字了,让编译器帮你去找。添加引用时告诉编译器,我这个程序使用了那些外部的库,他们都在那里。
那命名空间和程序集就只有调用与被调用的关系吗?
当然不是。在一个程序集中可以有不同的名称空间,同一个名称空间也可以分布在多个程序集上。名称空间只是类型名的一种扩展,它属于类型名的范畴。
实例解析:
命名空间和装配件:
装配件是.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。
到这里,我们可以清楚一个概念了,命名空间只是说明一个类型是那个族的,比如有人是汉族、有人是回族;而装配件表明一个类型住在哪里,比如有人住在北京、有人住在上海;那么北京有汉族人,也有回族人,上海有汉族人,也有回族人,这是不矛盾的。
关于命名空间和程序集,我解释了很多,不知道各位理解的怎么样!希望如果的大鸟批评指正。