原文: https://zetcode.com/lang/csharp/namespaces/

在 C# 教程的这一部分中,我们介绍了名称空间。

命名空间用于在最高逻辑级别上组织代码。 他们对公开给其他程序和应用的编程元素进行分类和呈现。 在一个名称空间内,我们可以声明另一个名称空间,一个类,一个接口,一个结构,一个枚举或一个委托。

我们无法定义诸如属性,变量和事件之类的项目。 这些项目必须在诸如结构或类之类的容器中声明。 当使用大量对象(例如类库)时,命名空间可防止歧义并简化引用。

命名空间在程序集中组织对象。 程序集是 CLR 应用的可重用,可版本控制和自描述的构建块。 程序集可以包含多个名称空间。 命名空间可以包含其他命名空间。 程序集提供了物理代码分组的基本单元。 命名空间提供了逻辑代码分组的基本单位。

C# 创建名称空间

namespace关键字用于在 C# 中声明一个名称空间。 命名空间的名称必须是有效的 C# 标识符名称。 命名空间用.运算符定界。 using指令消除了为每个类指定名称空间名称的要求。

C# 内置名称空间

内置库在名称空间内组织。

Program.cs

  1. public class Program
  2. {
  3. static void Main()
  4. {
  5. System.Console.WriteLine("Simple namespace example");
  6. }
  7. }

例如,Console类在System名称空间中可用。 要调用Console类的静态WriteLine()方法,我们使用其全限定名。 完全限定名称是对象引用,该引用以定义对象的名称空间的名称为前缀。

Program.cs

  1. using System;
  2. public class Program
  3. {
  4. static void Main()
  5. {
  6. Console.WriteLine("Simple namespace example");
  7. }
  8. }

通过using语句,我们将System命名空间包含到程序中。 现在我们可以调用Console.WriteLine()而不显式指定System

C# 共享名称空间

在下面的代码中,我们有两个共享相同名称空间的文件。

Counter.cs

  1. using System;
  2. namespace Sharing
  3. {
  4. class Counter
  5. {
  6. public int x = 0;
  7. public void Inc()
  8. {
  9. x += 100;
  10. Console.WriteLine(x);
  11. }
  12. }
  13. }

我们有一个Sharing命名空间。 在命名空间中,我们有一个Counter类。

  1. namespace Sharing
  2. {
  3. ...
  4. }

我们声明一个名为Sharing的命名空间。 该代码位于Sharing名称空间的大括号内。

Program.cs

  1. namespace Sharing
  2. {
  3. public class Program
  4. {
  5. static void Main()
  6. {
  7. var counter = new Counter();
  8. counter.Inc();
  9. counter.Inc();
  10. }
  11. }
  12. }

Program类中,我们使用上一个文件中的Counter类。 我们调用其Inc()方法。

  1. namespace Sharing
  2. {
  3. ...

我们在同一个命名空间中工作。

  1. var counter = new Counter();
  2. counter.Inc();
  3. counter.Inc();

我们创建Counter类的实例。 我们两次调用它的Inc()方法。 因为我们使用相同名称空间的对象,所以不需要显式指定其名称。

  1. $ dotnet run
  2. 100
  3. 200

这是示例输出。

C# 不同的名称空间

以下代码示例具有两个不同的名称空间。 我们使用using关键字从其他名称空间导入元素。

Basic.cs

  1. namespace Mathematical
  2. {
  3. public class Basic
  4. {
  5. public static double PI = 3.141592653589;
  6. public static double GetPi()
  7. {
  8. return PI;
  9. }
  10. }
  11. }

Basic类中,我们定义了PI常量和GetPi()方法。 Basic类在Mathematical命名空间中定义。

Program.cs

  1. using System;
  2. using Mathematical;
  3. namespace Distinct
  4. {
  5. public class Program
  6. {
  7. static void Main()
  8. {
  9. Console.WriteLine(Basic.PI);
  10. Console.WriteLine(Basic.GetPi());
  11. Console.WriteLine(Mathematical.Basic.PI);
  12. Console.WriteLine(Mathematical.Basic.PI);
  13. }
  14. }
  15. }

在此文件中,我们使用MyMath命名空间中的元素。

  1. using Mathematical;

我们将元素从MyMath命名空间导入到我们的命名空间中。

  1. Console.WriteLine(Basic.PI)
  2. Console.WriteLine(Basic.GetPI())

现在我们可以使用这些元素。 在我们的例子中,它是Basic类。

  1. Console.WriteLine(Mathematical.Basic.PI);
  2. Console.WriteLine(Mathematical.Basic.PI);

访问元素的另一种方法是指定元素的全限定名称。

  1. $ dotnet run
  2. 3.141592653589
  3. 3.141592653589
  4. 3.141592653589
  5. 3.141592653589

这是输出。

C# 根名称空间

根名称空间是 .NET Framework 库的主空间。 有人可能会创建与 .NET Framework 中的类型或名称空间冲突的类型或名称空间。 在这种情况下,我们可以使用global::前缀引用根名称空间。

Program.cs

  1. namespace ZetCode
  2. {
  3. class System
  4. {
  5. public override string ToString()
  6. {
  7. return "This is System class";
  8. }
  9. }
  10. public class Program
  11. {
  12. static void Main()
  13. {
  14. var sys = new System();
  15. global::System.Console.WriteLine(sys);
  16. }
  17. }
  18. }

ZetCode命名空间中,我们创建一个System类,该类与.NET Framework 中的类冲突。

var sys = new System();

在这里,我们从ZetCode命名空间引用System类。

global::System.Console.WriteLine(sys);

使用global::前缀,我们指向根名称空间的System类。

C# 默认名称空间

根名称空间也是 C# 程序的默认名称空间。 命名空间中未包含的元素将添加到未命名的默认命名空间中。

Program.cs

using System;

struct Book 
{
    public override string ToString()
    {
        return "Book struct in a default namespace";
    }
}

namespace MainProgram
{
    struct Book 
    {
        public override string ToString()
        {
            return "Book struct in a MainProgram namespace";
        }
    }

    public class Program
    {
        static void Main()
        {
            Book book1;
            global::Book book2;

            Console.WriteLine(book1);
            Console.WriteLine(book2);
        }
    }
}

我们有两个Book结构; 一个在MainProgram名称空间中定义,另一个在此名称空间之外定义。

struct Book 
{
    public override string ToString()
    {
        return "Book struct in a default namespace";
    }
}

Book结构在名为MainProgram的自定义命名空间之外定义。 它属于默认名称空间。

Book book1;

我们指的是MainProgram名称空间内定义的结构。

global::Book book2;

使用global::前缀,我们指向MainProgram命名空间之外定义的结构。

$ dotnet run
Book struct in a MainProgram namespace
Book struct in a default namespace

这是程序的输出。

C# 名称空间别名

using关键字可用于为名称空间创建别名。 使用嵌套的名称空间,全限定名称可能会变长。 我们可以通过创建别名来缩短它们。

Program.cs

namespace ZetCode
{
    namespace Items
    {
        class Book 
        {
            public override string ToString()
            {
                return "This is a book";
            }
        }
    } 
}

namespace MainProgram
{
    using ZIB = ZetCode.Items.Book;

    public class Aliases
    {
        static void Main()
        {
            ZetCode.Items.Book book =  new ZetCode.Items.Book();
            ZIB book2 = new ZIB();

            System.Console.WriteLine(book);
            System.Console.WriteLine(book2);
        }
    }
}

在示例中,我们为Book类创建了一个别名,该别名被两个名称空间包围。

namespace ZetCode
{
    namespace Items
    {
        class Book 
        {
        ...
        }
    } 
}

可以将一个名称空间嵌套到另一个名称空间中。 Book类的完全限定名称为ZetCode.Items.Book

using ZIB = ZetCode.Items.Book;

using关键字为全限定名ZetCode.Items.Book创建为ZIB别名。

ZetCode.Items.Book book =  new ZetCode.Items.Book();
ZIB book2 = new ZIB();

我们使用这两个名称来创建书籍实例。

C# 教程的这一部分专门用于名称空间。