接下来,我们将从以下五个方面来讲解命名空间:
- 定义命名空间
- 使用命名空间
- 正确理解命名空间含义
- 使用命名空间alias解决简单类名冲突
- 使用extern alias解决Assembly中的完整类名冲突
定义命名空间
namespace_name是以点号(.)作为层级隔离的。比如System.IO就可以认为System是第一层命名空间,IO是第二层命名空间。
在程序中使用特定类型的时候,我们需要使用完整的限定名,比如System.IO.MemoryStream。但是如果每次都这么写,除了增加了开发人员打字的成本,毫无益处。因此我们可以使用using关键字来表明我们需要使用某个命名空间中的类型。如下:
//使用完整限定名public static void Main() { System.Text.StringBuilder sb = new System.Text.StringBuilder();}//使用using 关键字using System.Text;public static void Main() { StringBuilder sb = new StringBuilder();}编译器遇到一个类型的时候,按照如下顺序查找:
- 查看当前源文件中是否有定义此类型
- 在当前定义的命名空间中查找是否有定义此类型
- 按定义顺序在using语句中的命名空间中进行查找
- 如果没有找到或者找到多个,抛出编译异常
正确理解命名空间含义
在上面的例子中,Class1可以直接访问到定义在Outer或者Outer.Middle命名空间中的类型而无需使用using语句进行引用。
当出现像上文提到的有两个Class1的情景时,使用全限定类名就变得不可避免。但是使用全限定名是一个很麻烦的事情,不光需要多打一些字,阅读代码也比较痛苦。为此,C#编译器允许我们使用别名alias来指代命名空间,原本的全限定名就可以使用“别名.类名"的形式来替代了。如下面的例子:
namespace A.B.C { using Middle = Outer.Middle; using Outer.Middle.Inner; public class ClassTest { public Class1 innerClazz1 = new Class1(); public Middle.Class1 middleClazz1 = new Middle.Class1(); }}注意:CLR本身并不知道这个alias的存在,CLR使用的永远是全限定类名。alias是C#编译器提供的便利,在编译阶段依然会将其替换成全限定名。
使用extern alias解决Assembly中的完整类名冲突
很多同学肯定很疑惑为什么会出现这种情况。这种情况确实应该尽力避免,所以提倡使用公司的域名作为命名空间的一部分。但是有时候难免两家公司提供的类型确实存在这种冲突,或者项目需要使用同一个Assembly的两个不同版本。
使用extern alias,我们需要:
- 给某个Assembly一个alias
- 在使用的类型中声明 extern alias <别名>
- 使用类型的时候,使用 <别名>::全限定类名 来访问
自此,我们就大致讲解完了关于namespace的一些知识点:
- 定义命名空间
- 使用命名空间
- 正确理解命名空间含义
- 使用命名空间alias解决简单类名冲突
- 使用extern alias解决Assembly中的完整类名冲突
如果觉得本文对你有帮助的话,欢迎给老白点赞收藏关注^_^
