C#中程序集与名称空间区别及冲突时解决方案

写两个点的东西,一个是程序集与名称空间的区别,另一点是,两个程序集(库)使用同一个名称空间,另一个程序集同时应用这两个库时发生的二义性及解决方法。

程序集在定义和使用上有很麻烦的地方,这里主要简要的能和名称空间区分开就好。关于强名,版本问题,私有程序集,共享程序集的问题可以参考文章最后给出的文档及MSDN。另外《C#入门经典》第三版中也有专门一个章节写这个,但是第四版的时候就被删减了。

程序集是.NET的最小逻辑单位,有两种主要的程序集。应用程序程序集(*.exe)这个具有入口点,另一个是库程序集(*.dll)没有入口点。更狭义一些我们可以说一个项目就是一个程序集。程序集是物理存在的。用于打包和部署。

名称空间只是为了把按逻辑划分,而产生的一个逻辑产物。和程序集没有必然联系。一个程序集可以使用,定义多个名称空间。不同程序集也可以使用相同的名称空间命。

程序集相关的文章

http://blog.csdn.net/hliq5399/archive/2008/03/20/2199129.aspx

http://www.cnblogs.com/wayfarer/archive/2006/04/07/369371.html

http://feng.westgis.ac.cn/2007/10/18/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E5%92%8C%E7%A8%8B%E5%BA%8F%E9%9B%86/

http://msdn.microsoft.com/zh-cn/library/hk5f40ct%28v=vs.80%29.aspx

这样就可能产生一个问题,有两个库CL1.dll和CL2.dll它们使用了同一个名称空间,而且相同名称空间下又有相同成员。例如代码如下

   1:  //CL1.cs
   2:  //csc target:library CL1.cs 
   3:  namespace CL
   4:  {
   5:      public class Test
   6:      {
   7:          public string getStr()
   8:          {
   9:              return "CL1-Test";
  10:          }
  11:      }
  12:      public class Test1
  13:      {
  14:          public string getStr()
  15:          {
  16:              return "CL1-Test1";
  17:          }
  18:      }
  19:  }
 
对库编译时,使用命令行记得要加参数,如果是VS下就不需要了。
   1:  //CL2.cs
   2:  namespace CL
   3:  {
   4:      public class Test
   5:      {
   6:          public string getStr()
   7:          {
   8:              return "CL2-Test";
   9:          }
  10:      }
  11:   
  12:      public class Test2
  13:      {
  14:          public string getStr()
  15:          {
  16:              return "CL2-Test2";
  17:          }
  18:      }
  19:  }

可以观察到两个库都使用了CL名称空间,如果同时应用他们,使用Test1 和Test2类的话都没有问题,万一需要使用Test类就会出现编译器不知道改找哪一个DLL文件中的Test类。

遇到这种情况需要用在编译时指定外部别名,并在代码中声明。我介绍在IDE下的使用方式,命令行下得参数给出参考文件比较简单。

新建一个控制台程序,并且添加CL1.dll和CL2.dll两个文件的引用。菜单-项目-添加引用-浏览,找到对应的库

然后在解决方法中点开引用,右键CL1-属性

12

将别名改为CL1。

这样就添加了一个命名空间别名,这样就相当为CL1中的别名添加了一个根。

具体使用看下面代码

   1:  extern alias CL1;
   2:  using System;
   3:  using System.Collections.Generic;
   4:  using System.Linq;
   5:  using System.Text;
   6:  using CL;
   7:   
   8:  namespace App
   9:  {
  10:      class Program
  11:      {
  12:          static void Main(string[] args)
  13:          {
  14:              CL1::CL.Test1 t1 = new CL1::CL.Test1();
  15:              Console.WriteLine(t1.getStr());
  16:   
  17:              Test2 t2 = new Test2();
  18:              Console.WriteLine(t2.getStr());
  19:   
  20:              CL1::CL.Test t = new CL1::CL.Test();
  21:              Console.WriteLine(t.getStr());
  22:   
  23:              Console.ReadKey();
  24:          }
  25:      }
  26:  }

extern alias CL1声明使用外部别名,这个必须在using语句之前。

然后我们就可以通过CL1::CL来使用CL1.class的CL名称空间。

::命名空间别名限定符运算符。

更多内容可以参考

http://msdn.microsoft.com/zh-cn/library/8fsksw8y%28v=VS.90%29.aspx

http://msdn.microsoft.com/zh-cn/library/64wh5743%28VS.90%29.aspx

http://msdn.microsoft.com/zh-cn/library/yabyz3h4%28v=VS.90%29.aspx

http://msdn.microsoft.com/zh-cn/library/ms173212%28v=VS.90%29.aspx

http://msdn.microsoft.com/zh-cn/library/htccxtad%28v=VS.80%29.aspx

你可能感兴趣的:(解决方案)