Csharp/C#教程:Json.Net反序列化构造函数与属性规则分享


Json.Net反序列化构造函数与属性规则

我正在使用Json.Net解决以下类的(反)序列化问题:

public class CoinsWithdrawn { public DateTimeOffset WithdrawlDate { get; private set; } public Dictionary NumberOfCoinsByType { get; private set; } public CoinsWithdrawn(DateTimeOffset withdrawDate, Dictionary numberOfCoinsByType) { WithdrawlDate = withdrawDate; NumberOfCoinsByType = numberOfCoinsByType; } } 

问题是构造函数参数“withdrawDate”的名称与属性名称“WithDrawlDate”不同。 使名称匹配(甚至忽略大小写)修复了问题。

但是,我想要更好地理解这一点,所以我恢复了代码并在将两个setter公之后进行了测试。 这也解决了这个问题。

最后,我从自动属性切换到具有支持字段的属性,以便我可以完全调试并查看实际发生的情况:

 public class CoinsWithdrawn { private DateTimeOffset _withdrawlDate; private Dictionary _numberOfCoinsByType; public DateTimeOffset WithdrawlDate { get { return _withdrawlDate; } set { _withdrawlDate = value; } } public Dictionary NumberOfCoinsByType { get { return _numberOfCoinsByType; } set { _numberOfCoinsByType = value; } } public CoinsWithdrawn(DateTimeOffset withdrawDate, Dictionary numberOfCoinsByType) { WithdrawlDate = withdrawDate; NumberOfCoinsByType = numberOfCoinsByType; } } 

我尝试使用和不使用默认构造函数(显示的代码省略了默认构造函数)。

使用默认构造函数:调用默认构造函数,然后调用两个属性设置器。

如果没有默认构造函数:调用非默认构造函数,则调用WithDrawlDate setter。 永远不会调用NumberOfCoinsByType setter。

我最好的猜测是反序列化器跟踪可以通过构造函数设置哪些属性(通过某些约定,因为似乎忽略了大小写),然后在可能的情况下使用属性设置器来填补空白。

这是它的工作方式吗? 是否在某处记录了反序列化的操作顺序/规则?

我最好的猜测是反序列化器跟踪可以通过构造函数设置哪些属性(通过某些约定,因为似乎忽略了大小写),然后在可能的情况下使用属性设置器来填补空白。 这是它的工作方式吗?

是的,这几乎就是要点。 如果您看一下自己可以看到的源代码 。 在JsonSerializerInternalReader类中,有一个方法CreateObjectUsingCreatorWithParameters ,它使用非默认构造函数处理对象的实例化。 我已经复制了下面的相关位。

ResolvePropertyAndCreatorValues方法从JSON中获取数据值,然后循环尝试将它们与构造函数参数进行匹配。 那些不匹配1的那些被添加到remainingPropertyValues字典中。 然后使用匹配的参数实例化对象,使用null / default值填充任何间隙。 稍后在该方法中的第二个循环(此处未示出)然后尝试在该对象上调用该字典中的剩余属性的setter。

 IDictionary propertyValues = ResolvePropertyAndCreatorValues(contract, containerProperty, reader, objectType, out extensionData); object[] creatorParameterValues = new object[contract.CreatorParameters.Count]; IDictionary remainingPropertyValues = new Dictionary(); foreach (KeyValuePair propertyValue in propertyValues) { JsonProperty property = propertyValue.Key; JsonProperty matchingCreatorParameter; if (contract.CreatorParameters.Contains(property)) { matchingCreatorParameter = property; } else { // check to see if a parameter with the same name as the underlying property name exists and match to that matchingCreatorParameter = contract.CreatorParameters.ForgivingCaseSensitiveFind(p => p.PropertyName, property.UnderlyingName); } if (matchingCreatorParameter != null) { int i = contract.CreatorParameters.IndexOf(matchingCreatorParameter); creatorParameterValues[i] = propertyValue.Value; } else { remainingPropertyValues.Add(propertyValue); } ... } ... object createdObject = creator(creatorParameterValues); ... 

1参数匹配算法本质上是一种不区分大小写的搜索,如果找到多个匹配项,则会回复为区分大小写。 如果您有兴趣,请查看ForgivingCaseSensitiveFind实用程序方法。

是否在某处记录了反序列化的操作顺序/规则?

不是我的知识。 官方文档在这里 ,但它没有涉及这个详细程度。

上述就是C#学习教程:Json.Net反序列化构造函数与属性规则分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/954521.html

(0)
上一篇 2021年11月20日
下一篇 2021年11月20日

精彩推荐