目录
一、命名空间
命名空间用于在最高逻辑级别组织代码。它们对暴露给其他程序和应用程序的编程元素进行分类和呈现。在命名空间中,我们可以声明另一个命名空间、类、接口、结构、枚举或委托。
我们不能定义诸如属性、变量和事件之类的项目。这些项目必须在结构或类等容器中声明。在使用诸如类库之类的大型对象组时,命名空间可以防止歧义并简化引用。
命名空间在程序集中组织对象。程序集是 CLR 应用程序的可重用、可版本控制和自描述的构建块。程序集可以包含多个命名空间。命名空间可以包含其他命名空间。程序集提供了物理代码分组的基本单元。命名空间提供了逻辑代码分组的基本单元。
注意:我们不能将顶级语句与命名空间一起使用。
二、C# 生成命名空间(namespace)
命名空间关键字用于在 C# 中声明命名空间。命名空间的名称必须是有效的 C# 标识符名称。命名空间用 . 分隔。操作员。 using 指令取消了为每个类指定命名空间名称的要求。
2.1 文件范围namespaces
C# 10 引入了文件范围的命名空间。当我们使用不带花括号的命名空间关键字时,整个文件就变成了一个命名空间。
2.2 内置namespaces
内置库在命名空间内组织。
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。
2.3 共享namespace
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
2.4 C# 明确的命名空间
下面的代码示例有两个不同的命名空间。我们使用 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
2.5 C# 根namespace
根命名空间是 .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 类。
2.6 C# 默认的 namespace
根命名空间也是 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
2.7 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();
我们使用这两个名称来创建书籍实例。