.NET 6新特性试用 | System.Text.Json序列化代码自动生成

前言

几乎所有.NET序列化程序的实现基础都是反射。下列代码是Newtonsoft.Json的实现:

protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{JsonProperty property = new JsonProperty();property.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member);property.DeclaringType = member.DeclaringType;property.ValueProvider = CreateMemberValueProvider(member);property.AttributeProvider = new ReflectionAttributeProvider(member);......
}

反射为某些场景提供了强大的功能,但相对于直接编码,在运行性能上较差,例如Newtonsoft.Json就用缓存进行了优化:

public virtual JsonContract ResolveContract(Type type)
{ValidationUtils.ArgumentNotNull(type, nameof(type));return _contractCache.Get(type);
}

而在.NET 6中,为System.Text.Json提供了Source Generator,可以在编译时就生成序列化源代码。

Demo

使用方法非常简单。

只需实现一个继承自JsonSerializerContext的类,并声明JsonSerializable,指定序列化的类型:

[JsonSerializable(typeof(WeatherForecast))]
internal partial class WeatherForecastContext : JsonSerializerContext
{
}

然后,就可以将自动生成的WeatherForecastContext.Default.WeatherForecast对象作为参数用于序列化:

var str = JsonSerializer.Serialize(new WeatherForecast
{TemperatureC = Random.Shared.Next(-20, 55),Summary = Summaries[Random.Shared.Next(Summaries.Length)]
}, WeatherForecastContext.Default.WeatherForecast);var obj = JsonSerializer.Deserialize(str, WeatherForecastContext.Default.WeatherForecast);

单步跟踪,可以看到生成的序列化代码如下,

private static void WeatherForecastSerializeHandler(global::System.Text.Json.Utf8JsonWriter writer, global::WebApplication1.WeatherForecast? value)
{if (value == null){writer.WriteNullValue();return;}writer.WriteStartObject();writer.WriteNumber(PropName_TemperatureC, value.TemperatureC);writer.WriteNumber(PropName_TemperatureF, value.TemperatureF);writer.WriteString(PropName_Summary, value.Summary);writer.WriteEndObject();
}

另外,还可以使用JsonSourceGenerationOptionsAttribute对生成的序列化代码进行一定调整,比如属性名大小写:

[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
[JsonSerializable(typeof(WeatherForecast))]
internal partial class WeatherForecastContext : JsonSerializerContext
{
}

结论

在编译时生成源代码可为.NET应用程序带来许多好处,包括提高性能。官方提供的测试结果表明提高了接近40%,有兴趣的朋友可以验证一下:

ff62abf7867be7b185fbecec8078a128.png

如果你觉得这篇文章对你有所启发,请帮忙点个或者在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/293754.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js去除左右空格

function yanzheng(val) {return val.replace(/(^\s*)|(\s*$)/g, "");}function Inputchecking() {var account document.getElementById("txt_ACCOUNT");if (yanzheng(account.value) "") {alert(请输入账号);account.focus();return false;}…

UVa 264 - Count on Cantor

《算法竞赛入门经典》5.4.1的题目,大意是,给出一个数表,如下: 第一项是1/1, 第二项是1/2, 第三项是2/1, 第四项是3/1, 第五项是2/2.....给一个正整数n,求第n项。 设第n个…

《SAS编程与数据挖掘商业案例》学习笔记之五

六:merge语句的使用(一个指针,一个pdv) merge语句是横向合并数据集,合并前必须两个数据集都要按照合并变量进行排序; proc sort datachapt3.merge_a;by x;run; proc sort datachapt3.merge_b;by bx;run; data ed; merge chapt3.me…

他解决了物理学千年争端,成就肩比牛顿、爱因斯坦,但却鲜有人知......

全世界只有3.14 % 的人关注了爆炸吧知识电磁学是经典物理学的一部分,提到电磁学就不得不提经典电动力学创始人-麦克斯韦。麦克斯韦的名气好像并不如牛顿、爱因斯坦那样家喻户晓,毕竟当提到牛顿的时候,这个公式就如同条件反射似得浮现出来&…

Windows 11 全新 4K 壁纸发布

微软近日发布 Windows 11 全新主题包 「Pantone Color of the Year 2022」,包含 4 张经重塑的壁纸。微软表示:通过这四张使用 Pantone Color of the Year 2022,,PANTONE 17-3938 Very Peri 颜色,重新定制的 Windows 11 Bloom 壁纸…

android之在view中内嵌浏览器的方法

我要做的一个东西是在一个页面的中间嵌入浏览器,一开始不知道从哪里开始,因为以前用的都是Textveiw或者editVeiw之类的控件,而它们并不能用来显示网页的内容,怎么办呢? 首先想到的是:是不是有一个用来显示网…

CCNA综合实验(一):实验拓扑与要求

一、实验拓扑 屏幕剪辑的捕获时间: 2013/5/5 星期日 16:49 IP地址分配 IP地址为192.168.1.0/24 ,,根据本地网络的需求制定子网划分方案。要求如下: R2(带有WIC-2T模块)上开启环回接口loopback 0 地址为 192.168.X.20;R…

《SAS编程与数据挖掘商业案例》学习笔记之六

八:modify语句((一个指针,两个pdv)) merge语句和update语句对数据集横向合并的主要功能还只能体现在匹配访问上,如通过by语句,对每个by组中的匹配数据集进行修改或更新,对于非常庞大的数据集需要…

C#开发微信门户及应用(10)--在管理系统中同步微信用户分组信息

在前面几篇文章中,逐步从原有微信的API封装的基础上过渡到微信应用平台管理系统里面,逐步介绍管理系统中的微信数据的界面设计,以及相关的处理操作过程的逻辑和代码,希望从更高一个层次,向大家介绍微信的应用开发过程。…

ASP.NET Web API中实现版本

一般来说,api 接口是提供给其他系统或是其他公司使用,不能随意频繁的变更。然而,需求和业务不断变化,接口和参数也会发生相应的变化。如果直接对原来的接口进行修改,势必会影响线其他系统的正常运行。这就必须对api 接…

一个娃娃竟然拍出50万......

1 瞎说什么大实话(素材来源网络,侵删)▼2 这个娃娃50万用来求婚用(素材来源网络,侵删)▼3 当代年轻人的特别祝福▼4 在福字底下加一横(素材来源网络,侵删)▼5 冰激凌…

切图崽的自我修养-规范CSS元素命名

前言 为什么我刚才写的样式乱了?!如何给变量,文件命名是程序员的老大难问题。命名为什么会这么难,因为它太重要了。可以这么说,准确的命名可以提高代码的可读性,让人容易理解,方便调试&#xff…

批量获取域名解析地址socketthread

import threadimport socketdef getIP(name,lock):print [%s]:%s\n%(name,socket.gethostbyname(name))lock.release() #释放线程锁def main():#读取存放域名的文件,文件是按一行一个域名的方式记录的files open(rC:\Users\Administrator\Desktop\python_script\na…

《SAS编程与数据挖掘商业案例》学习笔记之七

九:put语句 可以输出变量信息到指定地点,包括输出到sas系统的日志窗口; 输出到file语句规定的外部文件 输出到sas系统的output窗口 单尾操作符,多用于input语句中,双尾操作符,多用于put语句中。 Data a; In…

使用delphi 开发多层应用(二十二)使用kbmMW 的认证管理器

从kbmmw 4.4 开始,增加了认证管理器,这个比原来的简单认证提供了更多的功能。细化了很多权限操作。 今天对这一块做个介绍。 要做一个认证管理,大概分为以下5步: 1. 定义你要保护的资源,一般是服务、函数,…

算法分析笔记

2019独角兽企业重金招聘Python工程师标准>>> 定义 定义&#xff1a; 若存在正常数 c 和 n<sub>0</sub> 使得当 N ≥ n<sub>0</sub> 时 T(N) ≤ cf(N)&#xff0c;则记为 T(N) O(f(N))若存在正常数 c 和 n<sub>0</sub> 使得当 …

C++指针详解

C指针详解指针的概念 指针是一个特殊的变量&#xff0c;它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容&#xff1a;指针的类型&#xff0c;指针所指向的类型&#xff0c;指针的值或者叫指针所指向的内存区&#xff0c;还有指针本身所…

.NET 6新特性试用 | PriorityQueue

前言我们常用Queue<T>类来表示先进先出(FIFO)集合&#xff0c;集合中的对象按照放入顺序检索。例如&#xff1a;var jobs new Queue<Job>();jobs.Enqueue(new Job() { Id 1 }); jobs.Enqueue(new Job() { Id 2 }); jobs.Enqueue(new Job() { Id 3 });while (jo…