C# - 命名空间
C# - 命名空间(Namespaces)
Section titled “C# - 命名空间(Namespaces)”在 C# 中,命名空间(namespace)是组织和构建代码的基本概念。你可以把它想象成电脑上的文件夹系统。就像你使用文件夹来分组相关文件一样,你使用命名空间来分组相关的类(classes)、结构(structs)、接口(interfaces)以及其他类型。这可以防止命名冲突(naming collisions),即两个不同的类型意外地共享同一个名称。
定义命名空间
Section titled “定义命名空间”你可以使用 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{ // ...}使用命名空间中的类型
Section titled “使用命名空间中的类型”要使用命名空间中的类型,你必须提供它的完全限定名(fully qualified name),它包括命名空间和类型名,用点号(.)分隔:
// 使用完全限定名MyCompany.MyApplication.Data.UserRepository repo = new MyCompany.MyApplication.Data.UserRepository();using 指令
Section titled “using 指令”在每个地方都写完全限定名是很繁琐的。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.");global using 指令 (C# 10+)
Section titled “global using 指令 (C# 10+)”为了避免在每个文件中重复相同的 using 指令,你可以使用 global using 指令。这使得该命名空间在你的整个项目中都可用。这些通常放置在一个中心文件(如 GlobalUsings.cs)中。
// 在 GlobalUsings.cs 中global using System;global using MyCompany.MyApplication.Models;嵌套命名空间和命名约定
Section titled “嵌套命名空间和命名约定”命名空间可以嵌套以创建清晰的层次结构。标准约定是 CompanyName.ProductName.FeatureName。
namespace MyCompany.CoolApp.Authentication.OAuth; // 嵌套命名空间
public class GoogleAuthHandler{ // ...}使用别名解决命名冲突
Section titled “使用别名解决命名冲突”有时,两个命名空间可能包含同名的类型。这会造成歧义。你可以通过使用 using 指令创建命名空间别名(alias)来解决此问题。
using System;using ProjectA.Widgets;// 两个命名空间都有一个 'Widget' 类,导致冲突。// using ProjectB.Widgets;
// 创建一个别名来解决冲突using ProjectBWidget = ProjectB.Widgets.Widget;
var widgetA = new Widget(); // 这是 ProjectA.Widgets.Widgetvar 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指令。 - 使用别名来增加清晰度: 当出现冲突或类型名非常长且通用时,使用别名来提高代码可读性。