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

    技术2022-05-20  30

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

    程序集在定义和使用上有很麻烦的地方,这里主要简要的能和名称空间区分开就好。关于强名,版本问题,私有程序集,共享程序集的问题可以参考文章最后给出的文档及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/命名空间和程序集/

    http://msdn.microsoft.com/zh-cn/library/hk5f40ct(v=vs.80).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: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

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

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

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

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

    将别名改为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: }

    .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }extern alias CL1声明使用外部别名,这个必须在using语句之前。

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

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

    更多内容可以参考

    http://msdn.microsoft.com/zh-cn/library/8fsksw8y(v=VS.90).aspx

    http://msdn.microsoft.com/zh-cn/library/64wh5743(VS.90).aspx

    http://msdn.microsoft.com/zh-cn/library/yabyz3h4(v=VS.90).aspx

    http://msdn.microsoft.com/zh-cn/library/ms173212(v=VS.90).aspx

    http://msdn.microsoft.com/zh-cn/library/htccxtad(v=VS.80).aspx


    最新回复(0)