C# global using 全局引入

C# 10 引入了 global using ​ 指令,旨在简化代码,减少重复的 using​ 声明。它可以在项目级别定义全局生效的 using 语句,无需在每个代码文件中重复声明。

1. 什么是 global using

global using​ 是 C# 10 的一个特性,通过在 using​ 关键字前加上 global​ 关键字,使该命名空间在整个项目中全局生效。这样,项目内所有代码文件都能自动引用该命名空间,无需手动添加 using 指令。

示例:

csharp 复制代码
// 在任意 .cs 文件中使用
global using System.Text.Json;

声明后,项目中所有文件都可以直接使用 JsonSerializer​ 等类型,而不需要再写 using System.Text.Json;

2. 如何使用 global using

基本用法

  • 语法:global using <命名空间>;
  • 必须放在任何代码文件的顶部,不能 放在 namespace 声明内部。
  • 可以出现在任何 .cs 文件中,但推荐统一管理。

推荐实践:使用 GlobalUsings.cs 文件

在项目中创建一个名为 GlobalUsings.cs 的专用文件,将所有全局 using 集中管理。这是目前社区和微软推荐的最佳实践。

示例:

csharp 复制代码
// GlobalUsings.cs
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
global using Microsoft.EntityFrameworkCore;

默认的全局引用

当创建 .NET 6+ 新项目(如控制台、Web API 等)时,SDK 会隐式生成 常用命名空间的全局引用。这反映在项目文件中的 ImplicitUsings 设置:

xml 复制代码
<PropertyGroup>
    <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

启用后,以下命名空间会自动全局可用的(以控制台程序为例):

  • System
  • System.Collections.Generic
  • System.IO
  • System.Linq
  • System.Net.Http
  • System.Threading
  • System.Threading.Tasks

3. global using 的注意事项

不能放在 namespace 内部

csharp 复制代码
namespace MyApp
{
    global using System; // ❌ 编译错误
}

条件编译支持

global using 可以与条件编译结合:

csharp 复制代码
#if DEBUG
global using System.Diagnostics;
#endif

显式与隐式的关系

  • 隐式全局引用(由 SDK 自动生成)的命名空间可以删除。
  • 显式全局引用 (手动写的 global using)也可以通过显式声明来隐藏或覆盖。

多个文件中使用

global using 可以在多个文件中声明,但如果同一命名空间出现两次,会触发 CS8801 警告。确保同一命名空间只被声明一次。

4. 常见场景

场景 示例
基础库 global using System.Text.Json;
EF Core global using Microsoft.EntityFrameworkCore;
日志 global using Microsoft.Extensions.Logging;
依赖注入 global using Microsoft.Extensions.DependencyInjection;
自定义项目命名空间 global using MyApp.Common;

5. 总结

global using的优势:

  • 减少重复代码,提升开发效率
  • 统一管理项目引用,降低维护成本
  • 与新项目模板的 ImplicitUsings 配合使用效果更佳

适用建议:

  • 基础、稳定且项目全局使用的命名空间适合作为 global using(如 SystemSystem.Linq 等)
  • 特定于某个模块的命名空间仍建议使用传统 using,保持模块独立性