0

0

C# System.Text.Json源生成器方法 C#如何使用Source Generation模式提升JSON性能

幻夢星雲

幻夢星雲

发布时间:2026-03-10 13:08:03

|

607人浏览过

|

来源于php中文网

原创

system.text.json源生成器启用失败的常见原因包括未启用implicitusings和nullable、未引用正确版本包、未正确定义partial jsonserializercontext类及[jsonserializable]特性,且必须使用生成的上下文实例调用serialize/deserialize方法。

c# system.text.json源生成器方法 c#如何使用source generation模式提升json性能

System.Text.Json源生成器启用失败的常见原因

源生成器在 .NET 6+ 中默认不启用,即使项目 SDK 是 Microsoft.NET.Sdk,也必须显式开启源生成支持。最常被忽略的是未在 .csproj 中设置 ImplicitUsingsNullable,或未引用正确的包版本。

  • System.Text.Json 源生成依赖 System.Text.Json.SourceGeneration 包(.NET 7+ 内置,但需确认 SDK 版本;.NET 6 需手动安装 System.Text.Json 6.0.3+)
  • 项目必须启用 <implicitusings>enable</implicitusings>,否则 JsonSerializerContext 相关类型无法解析
  • 若使用 partial 类型定义上下文,类名必须以 JsonSerializerContext 结尾,且标记 [JsonSerializable] —— 否则生成器不触发
  • 生成器输出在 obj/Debug/netX.X/ 下的 GeneratedSources/ 文件夹中,若该目录为空,说明生成未执行,可检查 dotnet build -v:d 日志中是否有 SourceGenerator 相关警告

如何正确定义 JsonSourceGenerationContext

源生成器不是自动扫描所有类型,而是基于你声明的 JsonSerializerContext 子类,显式列出需要序列化的类型。这个类必须是 partial,且每个 [JsonSerializable] 属性对应一个根类型(支持嵌套、泛型、接口,但不支持 object 或未标注的运行时类型)。

艺映AI
艺映AI

艺映AI - 免费AI视频创作工具

下载
[JsonSerializable(typeof(Person))]
[JsonSerializable(typeof(List<Person>))]
[JsonSerializable(typeof(Dictionary<string, Order>))]
internal partial class AppJsonContext : JsonSerializerContext
{
}
  • PersonOrder 类本身不需要额外标记,但字段/属性访问必须为 public,或通过 [JsonInclude] 开放 private 成员
  • 若类型含 DateTimeOffsetGuid 等,无需额外配置,默认已优化;但自定义转换器(如 JsonConverter<t></t>)仍需在上下文中注册:[JsonSerializable(typeof(Person), TypeInfoPropertyName = "PersonInfo")] + 手动实现 PersonInfo 属性
  • 不支持动态类型(如 ExpandoObject)、dynamic、未闭合泛型(List)—— 这些会跳过生成,回退到反射路径

序列化/反序列化时如何正确使用生成的上下文

启用源生成后,不能继续用静态 JsonSerializer.Serialize<t>(value)</t>,那仍走反射路径。必须传入生成的 AppJsonContext.Default 实例,并使用其 Serialize/Deserialize 方法,才能命中编译期生成的代码路径。

var context = AppJsonContext.Default;
string json = context.Serialize(person); // ✅ 调用生成的代码
Person p = context.Deserialize<Person>(json); // ✅

// ❌ 以下仍走反射,完全绕过源生成
string json2 = JsonSerializer.Serialize(person);
Person p2 = JsonSerializer.Deserialize<Person>(json2);
  • AppJsonContext.Default 是线程安全的单例,可全局复用,无需缓存或池化
  • 若需不同选项(如 PropertyNamingPolicy),必须定义多个 partial 上下文类,每个带独立 [JsonSourceGenerationOptions] 特性;无法在运行时切换同一上下文的选项
  • 生成代码对 null 值处理与反射路径一致,但字段级 JsonIgnore 必须在类型定义时存在,运行时通过 JsonSerializerOptions 添加的忽略规则无效

性能差异在哪?什么场景下值得上源生成

源生成主要消除反射调用和运行时类型检查开销,在高频、小对象、固定结构的 JSON 场景下收益明显(如微服务间 DTO 通信、API 响应序列化)。但它的优势不是“绝对更快”,而是“更稳定”——避免 JIT 编译抖动和 GC 压力波动。

  • 典型提升:10–30% 吞吐量(Serialize),反序列化可达 2× 以上(尤其含集合或深层嵌套时)
  • 真正关键收益是首次调用无 JIT 延迟:反射路径首次 Serialize<t></t> 可能卡住 5–20ms;源生成代码在编译时就产出 IL,启动即可用
  • 不适合场景:类型结构高度动态(如配置驱动的 JSON Schema)、开发期频繁改模型(每次改都要 rebuild 才能更新生成代码)、或仅偶尔序列化大文件(此时 IO 或压缩才是瓶颈)
  • 调试时注意:生成的代码在 obj/ 下,VS 默认不加载,需在调试设置中启用 “Enable source server support” 并勾选 “Enable Just My Code” 外的符号加载,否则断点进不到生成方法里

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

454

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

546

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

334

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

253

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1089

2024.03.01

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

253

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1089

2024.03.01

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

4

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 10.1万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号