• 详解C#中的命名空间


    命名空间

    C#中使用namespace关键字定义命名空间,命名空间类似我们电脑文件资源管理器中的文件夹,可自由命名且具有层级,命名空间中的各个类就像文件夹中的文件,通过各种命名及划分层级来分类存放

    namespace

    命名空间通过关键字namespace定义,使用"."或者{}包含来定义嵌套的命名空间,如下面两段代码在语义上是等价的:

    namespace Outer.Middle.Inner
    {
        class Class1 { }
        class Class2 { }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    namespace Outer
    {
        namespace Middle 
        { 
            namespace Inner
            {
                class Class1 { }
                class Class2 { }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    如果类型没有在任何命名空间中定义,则它存在于全局命名空间. 全局命名空间包含了顶层命名空间,如上例中的Outer命名空间

    using

    using指令用于导入命名空间,可以避免使用完全限定名称来指代某种类型.以下例子导入了上述例子中的Outer.Middle.Inner命名空间:

        using Outer.Middle.Inner;
        class Test
        {
            static void Main()
            {
                Class1 c1; //此处不需要一层层指定Class1的命名空间,因为已经通过using引入了
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    using static

    使用using static可以引用命名空间中的静态成员,包括字段,属性及嵌套类型.如下例中我们引用Console类的静态成员后可直接调用WriteLine方法:

    using static System.Console;
    WriteLine("Hello, World!");
    
    • 1
    • 2

    注意using static指令只能用于类型,不能用于命名空间(将产生一个编译错误)
    using static不能直接引入命名空间
    using static除了能导入静态成员外还能导入枚举类型:

    using static System.Windows.Visibility;
    var textBox = new TextBox{ Visibility = Hidden}; //此处不需要指定Visibility.Hidden
    
    • 1
    • 2

    命名空间中的规则

    名称范围

    外层命名空间中声明的名称能够直接在内层命名空间中使用

    namespace Outer
    {
        public class OuterClass { }
        namespace Middle 
        { 
            namespace Inner
            {
                class Class1:OuterClass { }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    命名空间分层结构中不同分支中的类型需要使用部分限定名称

    namespace Outer
    {
        public class OuterClass { }
        namespace Middle 
        { 
            namespace Inner
            {
                class Class1:OuterClass { }
            }
            namespace Inner2
            {
                class Class2:Inner.Class1 { } //此处不能直接使用Class1
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    名称隐藏

    如果同一类型名称同时出现在外层和内层命名空间中,则内层名称优先.如果要使用外层类型,必须使用它的完全限定名称:

    namespace Outer
    {
        public class One { }
        namespace Inner
        {
            class One { }
            class Test
            {
                One inner;// = Outer.Inner.One
                Outer.One outer; // =Outer.One
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    所有类型名称在编译时都会转化为完全限定名称.中间语言(IL)代码不包含非限定名称和部分限定名称.

    重复的命名空间

    只要命名空间中的类型名称不冲突就可以重复声明同一个命名空间:

    namespace Outer
    {
        class Class1 { }
    }
    namespace Outer
    {
        class Class2 { }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    上述示例和在Outer命名空间中同时定义Class1和Class2语义上是一样的,上面两个类也可以分别定义在两个不同的源文件,编译到不同的程序集中去.

    命名空间别名

    导入命名空间可能会导致类型名称的冲突,这时我们可以为导入的类型或者命名空间创建别名,如下:

    using Assembly2 =System.Reflection.Assembly; //给命名空间中的指定类型创建别名
    class Program
    {
        Assembly2 asm; //= System.Reflection.Assembly
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    using R = System.Reflection; //给整个命名空间创建别名
    class Program
    {
        R.Assembly asm; //= System.Reflection.Assembly
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    命名空间别名限定符

    之前提到,由于内层命名空间中的名称优先级更高会隐藏外层命名空间中的名称.有时即使使用类型的完全限定名称也无法解决冲突,如下示例:

    namespace N
    {
        class A
        {
            A.B b;  //此处虽然使用完全限定名称,但还是会拿到嵌套类B的实例,而不是A命名空间下的类B
            class B { }
        }
    }
    namespace A
    {
        class B { }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    要解决这样的冲突,可以使用全局命名空间global来限定命名空间中的名称:

    namespace N
    {
        class A
        {
            global::A.B b;  //通过global限定全局命名空间下的A命名空间中的类B
            class B { }
        }
    }
    namespace A
    {
        class B { }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    正确理解线程WAITING状态
    函数式接口 ( Java 8新特性 )
    混合灰狼和布谷鸟搜索优化算法(Matlab完整代码实现)
    从React源码来学hooks是不是更香呢
    第五章:最新版零基础学习 PYTHON 教程—Python 字符串操作指南(第四节 - Python 中的字符串反转6种不同的方式方法)
    从零开始学YC-Framework之鉴权
    IDEA 连接 数据库
    《Java基础知识》Java 反射详解
    英语——分享篇——每日200词——2201-2400
    SpringBoot源码深度解析(三):SpringBoot启动流程原理详解
  • 原文地址:https://blog.csdn.net/Leaderxin/article/details/124597667