C# 使用 Source Generation 提升 System.Text.Json 性能
使用 Source Generation 提升 System.Text.Json 性能
- 使用 Source Generation 提升 System.Text.Json 性能
- 前言
- 一、源生成的核心优势
- 二、实现步骤
- 1. 定义序列化上下文
- 2. 序列化/反序列化
- 三、高级配置
- 四、项目集成
- 五、关键注意事项
- 六、完整案例
- 数据模型
- 上下文定义
- 使用示例
- 结语
使用 Source Generation 提升 System.Text.Json 性能
前言
在 C# 开发中,System.Text.Json
是处理 JSON 数据的主流方案。传统的反射式序列化虽然方便,但在高频调用和AOT场景(如 iOS/Blazor WASM)中会遇到性能瓶颈。.NET 6+ 引入的 Source Generation(源生成) 技术,通过在编译时生成序列化代码,可显著提升性能。本文将详解其实现方式。
一、源生成的核心优势
特性 | 反射方案 | 源生成方案 |
---|---|---|
启动速度 | 首次调用需初始化反射元数据 | 无运行时开销 |
AOT 支持 | 不可用 | 完全支持 |
序列化吞吐量 | 约 1x | 约 1.5-2x |
内存占用 | 较高(反射缓存) | 低(编译时生成代码) |
适用场景:
- 需要减少应用启动时间的服务
- 移动端/WebAssembly 等 AOT 环境
- 高频调用的 JSON API 接口
二、实现步骤
1. 定义序列化上下文
创建继承自 JsonSerializerContext
的分部类,并通过 [JsonSerializable]
注册类型:
[JsonSerializable(typeof(Product))]
[JsonSerializable(typeof(List<Product>))]
public partial class AppJsonContext : JsonSerializerContext
{// 源生成器自动填充实现
}
2. 序列化/反序列化
使用生成的 Default
实例进行高效操作:
// 序列化
var product = new Product { Id = 100, Name = "Keyboard" };
string json = JsonSerializer.Serialize(product, AppJsonContext.Default.Product);// 反序列化
Product? result = JsonSerializer.Deserialize(json, AppJsonContext.Default.Product);
三、高级配置
通过 [JsonSourceGenerationOptions]
定制行为:
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,WriteIndented = true,DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,NumberHandling = JsonNumberHandling.AllowReadingFromString)]
[JsonSerializable(typeof(Product))]
public partial class AppJsonContext : JsonSerializerContext
{
}
常用配置项:
PropertyNamingPolicy
: 命名策略(如 CamelCase)WriteIndented
: 是否美化输出IgnoreNullValues
: 空值忽略规则Converters
: 自定义类型转换器
四、项目集成
在 .csproj
中启用源生成:
<PropertyGroup><EnableSourceGenerator>true</EnableSourceGenerator>
</PropertyGroup>
注意:需安装
System.Text.Json
7.0+ 包
五、关键注意事项
-
类型可见性
如果目标类型为internal
,需在AssemblyInfo.cs
添加:[assembly: InternalsVisibleTo("YourAssemblyName")]
-
编译时验证
所有被序列化的属性必须具有可访问的getter/setter
-
集合类型
建议直接注册List<T>
而非IEnumerable<T>
以提高性能
六、完整案例
数据模型
public class Product
{public int Id { get; set; }public string? Name { get; set; }public DateTimeOffset CreatedAt { get; set; }
}
上下文定义
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Product))]
public partial class ProductContext : JsonSerializerContext
{
}
使用示例
var products = new List<Product>
{new Product { Id = 1, Name = "Mouse", CreatedAt = DateTimeOffset.UtcNow },new Product { Id = 2, Name = "Monitor", CreatedAt = DateTimeOffset.UtcNow }
};// 序列化集合
string json = JsonSerializer.Serialize(products, ProductContext.Default.ListProduct
);// 输出结果
// [
// {
// "Id": 1,
// "Name": "Mouse",
// "CreatedAt": "2023-09-20T08:30:00+00:00"
// },
// ...
// ]
结语
源生成技术通过编译时生成优化代码,不仅提升了性能,还增强了 AOT 兼容性。对于追求极致性能的 .NET 应用,这是 JSON 处理的首选方案。建议在复杂DTO场景中优先采用此方案。