You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Newtonsoft.Json反序列化带排序逻辑的自定义集合失败问题

问题根因

Newtonsoft.Json 处理可读写的集合类型属性时,默认反序列化流程为:

  1. 调用属性getter获取现有集合实例
  2. 将反序列化得到的所有元素逐个Add到该实例中

你修改后的属性getter每次执行都会通过OrderBy(...).ToList()生成一个和后备字段_inventoryItems无关联的全新List实例。反序列化器添加元素的操作全部作用在这个临时生成的List上,操作完成后临时实例被回收,真正的后备字段始终保持初始化的空列表状态,最终读取到的Items自然是空的。

无需自定义转换器的解决方法

方案1(推荐):调整排序逻辑位置,符合反序列化默认逻辑

把排序逻辑从getter移到setter,保证getter直接返回后备字段的真实引用,既兼容默认反序列化行为,还能避免每次访问属性都重复排序、生成新集合的性能损耗:

class Inventory
{
    private List<InventoryItem> _inventoryItems = new();

    public List<InventoryItem> Items
    {
        get => _inventoryItems;
        set 
        {
            _inventoryItems = value == null 
                ? new List<InventoryItem>() 
                : value.OrderBy(t => t.Start).ToList();
        }
    }
}

这种实现下,无论是外部赋值还是Json反序列化,存入后备字段的集合永远是按Start字段排好序的,读取时直接返回即可,没有额外开销。

方案2:修改反序列化配置,适配原有属性写法

如果业务场景必须保留getter动态排序返回新集合的逻辑,不需要修改类代码,只要调整反序列化设置,让Json.NET直接生成完整集合后调用setter赋值,跳过逐个Add的流程即可:

var deserializeSettings = new JsonSerializerSettings
{
    ObjectCreationHandling = ObjectCreationHandling.Replace
};
var inventory = JsonConvert.DeserializeObject<Inventory>(serialization, deserializeSettings);

如果需要全局生效,直接将该配置赋值给JsonConvert.DefaultSettings即可,所有反序列化操作都会自动应用该规则。

内容的提问来源于stack exchange,提问作者Aaron Haspel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:39:19