Skip to content

C# - 命名空间

在 C# 中,命名空间(namespace)是组织和构建代码的基本概念。你可以把它想象成电脑上的文件夹系统。就像你使用文件夹来分组相关文件一样,你使用命名空间来分组相关的类(classes)、结构(structs)、接口(interfaces)以及其他类型。这可以防止命名冲突(naming collisions),即两个不同的类型意外地共享同一个名称。

你可以使用 namespace 关键字来定义一个命名空间。有两种常见的方式:

1. 块级命名空间(Block-Scoped Namespaces)(传统方式)

Section titled “1. 块级命名空间(Block-Scoped Namespaces)(传统方式)”

传统语法将代码包含在花括号 {} 内。这对于在单个文件中定义多个命名空间很有用。

namespace MyCompany.MyApplication.Services
{
// Services 功能的代码,例如类、接口
public class NotificationService
{
// ...
}
}

2. 文件级命名空间(File-Scoped Namespaces)(现代方式 - C# 10 及更高版本)

Section titled “2. 文件级命名空间(File-Scoped Namespaces)(现代方式 - C# 10 及更高版本)”

现代 C# 开发推荐使用文件级命名空间。这种更简洁的语法声明文件中的所有类型都属于指定的命名空间,从而减少了缩进和样板代码(boilerplate code)。

namespace MyCompany.MyApplication.Data;
// 此文件中的所有类型现在都位于 MyCompany.MyApplication.Data 命名空间中
public class UserRepository
{
// ...
}

要使用命名空间中的类型,你必须提供它的完全限定名(fully qualified name),它包括命名空间和类型名,用点号(.)分隔:

// 使用完全限定名
MyCompany.MyApplication.Data.UserRepository repo = new MyCompany.MyApplication.Data.UserRepository();

在每个地方都写完全限定名是很繁琐的。using 指令允许你导入命名空间中的所有类型,这样你就可以直接通过类型名来引用它们。这在所有 C# 项目中都是标准做法。

using System;
using MyCompany.MyApplication.Data; // 导入 Data 命名空间
using MyCompany.MyApplication.Services; // 导入 Services 命名空间
// 现在我们可以直接使用这些类型了
var userRepository = new UserRepository();
var notificationService = new NotificationService();
Console.WriteLine("Services initialized successfully.");

为了避免在每个文件中重复相同的 using 指令,你可以使用 global using 指令。这使得该命名空间在你的整个项目中都可用。这些通常放置在一个中心文件(如 GlobalUsings.cs)中。

// 在 GlobalUsings.cs 中
global using System;
global using MyCompany.MyApplication.Models;

命名空间可以嵌套以创建清晰的层次结构。标准约定是 CompanyName.ProductName.FeatureName。

namespace MyCompany.CoolApp.Authentication.OAuth; // 嵌套命名空间
public class GoogleAuthHandler
{
// ...
}

有时,两个命名空间可能包含同名的类型。这会造成歧义。你可以通过使用 using 指令创建命名空间别名(alias)来解决此问题。

using System;
using ProjectA.Widgets;
// 两个命名空间都有一个 'Widget' 类,导致冲突。
// using ProjectB.Widgets;
// 创建一个别名来解决冲突
using ProjectBWidget = ProjectB.Widgets.Widget;
var widgetA = new Widget(); // 这是 ProjectA.Widgets.Widget
var widgetB = new ProjectBWidget(); // 这是 ProjectB.Widgets.Widget
Console.WriteLine($"Created a widget of type {widgetA.GetType().FullName}");
Console.WriteLine($"Created a widget of type {widgetB.GetType().FullName}");
  • 使用文件级命名空间: 在新项目中,首选 namespace ...; 语法,以保持文件简洁。
  • 遵循标准约定: 使用 CompanyName.ProductName.Feature 这样的分层命名方案,以使代码库组织有序且直观。
  • 使用 global using: 对于常用命名空间(如 System、System.Linq、项目的 Models 命名空间),在 GlobalUsings.cs 文件中定义它们,以减少样板代码。
  • 避免类型污染(Type Pollution): 只导入你实际需要的命名空间。如果你没有使用该命名空间中的任何类型,就不要添加 using 指令。
  • 使用别名来增加清晰度: 当出现冲突或类型名非常长且通用时,使用别名来提高代码可读性。