详解C#中的命名空间

命名空间

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

namespace

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

namespace Outer.Middle.Inner
{
    class Class1 { }
    class Class2 { }
}
namespace Outer
{
    namespace Middle 
    { 
        namespace Inner
        {
            class Class1 { }
            class Class2 { }
        }
    }
}

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

using

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

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

using static

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

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

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

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

命名空间中的规则

名称范围

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

namespace Outer
{
    public class OuterClass { }
    namespace Middle 
    { 
        namespace Inner
        {
            class Class1:OuterClass { }
        }
    }
}

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

namespace Outer
{
    public class OuterClass { }
    namespace Middle 
    { 
        namespace Inner
        {
            class Class1:OuterClass { }
        }
        namespace Inner2
        {
            class Class2:Inner.Class1 { } //此处不能直接使用Class1
        }
    }
}

名称隐藏

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

namespace Outer
{
    public class One { }
    namespace Inner
    {
        class One { }
        class Test
        {
            One inner;// = Outer.Inner.One
            Outer.One outer; // =Outer.One
        }
    }
}

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

重复的命名空间

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

namespace Outer
{
    class Class1 { }
}
namespace Outer
{
    class Class2 { }
}

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

命名空间别名

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

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

命名空间别名限定符

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

namespace N
{
    class A
    {
        A.B b;  //此处虽然使用完全限定名称,但还是会拿到嵌套类B的实例,而不是A命名空间下的类B
        class B { }
    }
}
namespace A
{
    class B { }
}

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

namespace N
{
    class A
    {
        global::A.B b;  //通过global限定全局命名空间下的A命名空间中的类B
        class B { }
    }
}
namespace A
{
    class B { }
}
  • 5
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值