Newtonsoft循环引用与自引用反序列化null值问题

文章讨论了Newtonsoft在处理循环引用和自引用时,即使序列化设置正确,反序列化后可能出现null值的问题。解决方案是使用默认构造函数进行反序列化。文中还解释了为何非默认构造函数可能导致这种问题,以及ISerialized类型的例子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景:

Newtonsoft循环引用与自引用反序列化null值问题

问题描述

正确设置了PreserveReferencesHandling.ObjectsReferenceLoopHandling.Serialize
序列化成功,json文件中确实被记录,反序列化后JsonConvert.DeserializeObject反序列化完成得到空值

原因分析:

空值为引用项,在json文件中发生自引用或循环引用,即A引用了A自身或A引用了B,而B又引用了A,即便设置了PreserveReferencesHandling.ObjectsReferenceLoopHandling也只能达到A引用B,C引用B的情况下被正确设置,无法避免反序列化之后自引用为null值或循环引用B对A的引用为null

解决方案:

使用默认构造函数进行反序列化

对于自引用与循环引用的详细分析

官方文档PreserveReferencesHandling下的Note已经写明

当通过非默认构造函数设置值时,无法保留引用。对于非默认构造函数,子值必须在父值之前创建,以便它们可以传递到构造函数中,从而无法跟踪引用。 ISerialized 类型是一个类的示例,其值使用非默认构造函数填充,并且不能与 PreserveReferencesHandling 一起使用。

所以推测反序列化一个类时,如果使用默认无参构造函数则继续反序列化,而如果使用非默认有参构造函数,则会停止这个类的反序列化,优先序列化这个类父值下面的成员子值,以便将子值作为参数传入构造函数在参数与子值成员名相同的情况下,会使用构造函数反序列化,名称无视大小写,这就导致子值在反序列化时,他们对于父值的引用为null,因为此时父值还未创建,而json文件中又是使用ref对父值的id进行引用,而不会在此反序列化父值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值