目录
命名空间用于在最高逻辑级别组织代码。它们对暴露给其他程序和应用程序的编程元素进行分类和呈现。在命名空间中,我们可以声明另一个命名空间、类、接口、结构、枚举或委托。
我们不能定义诸如属性、变量和事件之类的项目。这些项目必须在结构或类等容器中声明。在使用诸如类库之类的大型对象组时,命名空间可以防止歧义并简化引用。
命名空间在程序集中组织对象。程序集是 CLR 应用程序的可重用、可版本控制和自描述的构建块。程序集可以包含多个命名空间。命名空间可以包含其他命名空间。程序集提供了物理代码分组的基本单元。命名空间提供了逻辑代码分组的基本单元。
注意:我们不能将顶级语句与命名空间一起使用。
命名空间关键字用于在 C# 中声明命名空间。命名空间的名称必须是有效的 C# 标识符名称。命名空间用 . 分隔。操作员。 using 指令取消了为每个类指定命名空间名称的要求。
C# 10 引入了文件范围的命名空间。当我们使用不带花括号的命名空间关键字时,整个文件就变成了一个命名空间。
内置库在命名空间内组织。
Program.cs
- var hostName = System.Net.Dns.GetHostName();
- Console.WriteLine($"Hostname: {hostName}");
例如,GetHostName 函数在 System.Net.Dns 命名空间中可用。要调用该方法,我们使用其完全限定名称。完全限定名称是以定义对象的命名空间名称为前缀的对象引用。
Program.cs
- using System.Net;
-
- var hostName = Dns.GetHostName();
- Console.WriteLine($"Hostname: {hostName}");
通过 using 语句,我们将 System.Net 命名空间包含到我们的程序中。现在我们可以调用 Dns.GetHostName 而无需明确指定 System.Net。
In the following code, we have two files that share the same namespace.
Counter.cs
- namespace Sharing;
- class Counter
- {
- public int x = 0;
- public void Inc()
- {
- x += 100;
- Console.WriteLine(x);
- }
- }
我们有一个共享命名空间。在命名空间中,我们有一个 Counter 类。
namespace Sharing;
我们声明了一个名为“共享”的命名空间。命名空间适用于当前文件。
Program.cs
- namespace Sharing;
-
- public class Program
- {
- static void Main()
- {
- var counter = new Counter();
-
- counter.Inc();
- counter.Inc();
- }
- }
在 Program 类中,我们使用上一个文件中的 Counter 类。我们调用它的 Inc 方法。
namespace Sharing
{
...
我们在同一个命名空间中工作。
var counter = new Counter();
counter.Inc();
counter.Inc();
我们创建一个 Counter 类的实例。我们两次调用它的 Inc 方法。因为我们使用相同命名空间的对象,所以我们不需要明确指定其名称。
$ dotnet run 100 200
下面的代码示例有两个不同的命名空间。我们使用 using 关键字从不同的命名空间导入元素。
Basic.cs
namespace Mathematical;
public class Basic
{
public static double PI = 3.141592653589;
public static double GetPi()
{
return PI;
}
}
在 Basic 类中,我们定义了一个 PI 常量和一个 GetPi 方法。基本类在数学命名空间中定义。
Program.cs
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 命名空间中的元素。
using Mathematical;
我们将 MyMath 命名空间中的元素导入到我们的命名空间中。
Console.WriteLine(Basic.PI) Console.WriteLine(Basic.GetPI())
现在我们可以使用这些元素了。在我们的例子中,它是 Basic 类。
Console.WriteLine(Mathematical.Basic.PI); Console.WriteLine(Mathematical.Basic.PI);
访问元素的另一种方法是指定元素的完全限定名称。
$ dotnet run
3.141592653589
3.141592653589
3.141592653589
3.141592653589
根命名空间是 .NET Framework 库的主空间。有人可能会创建与 .NET Framework 中的类型或命名空间发生冲突的类型或命名空间。在这种情况下,我们可以使用 global:: 前缀来引用根命名空间。
Program.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 中的类发生冲突。
var sys = new System();
这里我们指的是来自 ZetCode 命名空间的 System 类。
global::System.Console.WriteLine(sys);
使用 global:: 前缀,我们指向根命名空间的 System 类。
根命名空间也是 C# 程序的默认命名空间。未包含在命名空间中的元素将添加到未命名的默认命名空间中。
Program.cs
- 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);
- }
- }
- }
我们有两种书本结构;一个在 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
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();
我们使用这两个名称来创建书籍实例。