# 命名空间

> 原文： [https://zetcode.com/lang/csharp/namespaces/](https://zetcode.com/lang/csharp/namespaces/)

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

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

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

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

## C# 创建名称空间

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

## C# 内置名称空间

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

`Program.cs`

```cs
public class Program
{
    static void Main()
    {
        System.Console.WriteLine("Simple namespace example");
    }
}

```

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

`Program.cs`

```cs
using System;

public class Program
{
    static void Main()
    {
        Console.WriteLine("Simple namespace example");
    }
}

```

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

## C# 共享名称空间

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

`Counter.cs`

```cs
using System;

namespace Sharing
{
    class Counter
    {
        public int x = 0;

        public void Inc()
        {
            x += 100;
            Console.WriteLine(x);
        } 
    }
}

```

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

```cs
namespace Sharing
{
...
}

```

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

`Program.cs`

```cs
namespace Sharing
{
    public class Program
    {
        static void Main()
        {
            var counter = new Counter();

            counter.Inc();
            counter.Inc();
        }
    }
}

```

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

```cs
namespace Sharing
{
...

```

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

```cs
var counter = new Counter();

counter.Inc();
counter.Inc();

```

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

```cs
$ dotnet run
100
200

```

这是示例输出。

## C# 不同的名称空间

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

`Basic.cs`

```cs
namespace Mathematical
{
    public class Basic
    {
        public static double PI = 3.141592653589;

        public static double GetPi()
        {
            return PI;
        } 
    }
}

```

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

`Program.cs`

```cs
using System;
using Mathematical;

namespace Distinct
{
    public class Program
    {
        static void Main()
        {
            Console.WriteLine(Basic.PI);
            Console.WriteLine(Basic.GetPi());

            Console.WriteLine(Mathematical.Basic.PI);
            Console.WriteLine(Mathematical.Basic.PI);
        }
    }
}

```

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

```cs
using Mathematical;

```

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

```cs
Console.WriteLine(Basic.PI)
Console.WriteLine(Basic.GetPI())

```

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

```cs
Console.WriteLine(Mathematical.Basic.PI);
Console.WriteLine(Mathematical.Basic.PI);

```

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

```cs
$ dotnet run
3.141592653589
3.141592653589
3.141592653589
3.141592653589

```

这是输出。

## C# 根名称空间

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

`Program.cs`

```cs
namespace ZetCode
{
    class System 
    {
        public override string ToString() 
        {
            return "This is System class";
        }
    }

    public class Program
    {
        static void Main()
        {
            var sys = new System();
            global::System.Console.WriteLine(sys); 
        }
    }    
}

```

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

```cs
var sys = new System();

```

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

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

```

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

## C# 默认名称空间

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

`Program.cs`

```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`名称空间中定义，另一个在此名称空间之外定义。

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

```

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

```cs
Book book1;

```

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

```cs
global::Book book2;

```

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

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

```

这是程序的输出。

## C# 名称空间别名

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

`Program.cs`

```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`类创建了一个别名，该别名被两个名称空间包围。

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

```

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

```cs
using ZIB = ZetCode.Items.Book;

```

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

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

```

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

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