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

如何使用自定义JsonConverter反序列化组合模式的复合列表对象

实现思路

  • 区分节点类型:反序列化时首先判断当前JToken类型,若JObject仅包含1个键且对应值为JArray,则该节点为Composite节点,键名即为Composite的name属性;若JObject包含experience、name等叶子节点专属字段,则为Leaf节点。
  • 递归处理子节点:Composite的子节点数组可通过递归逻辑逐个解析,子节点可能是Composite也可能是Leaf,按上述规则判断后递归解析即可。

完整实现代码

你可以直接在现有CompositeConverter类中补充ReadJson实现即可:

public class CompositeConverter : JsonConverter
{
    // 原有序列化逻辑可以优化,不需要反射直接访问属性
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Composite composite = (Composite)value;
        JArray array = new JArray();
        foreach (Component e in composite._children)
        {
            array.Add(JToken.FromObject(e, serializer));
        }
        JObject obj = new JObject();
        obj.Add(composite.name, array);
        obj.WriteTo(writer);
    }

    // 新增反序列化逻辑
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jObj = JObject.Load(reader);
        // Composite节点仅会有一个属性,属性名为name,值为子节点数组
        var compositeProp = jObj.Properties().First();
        string compositeName = compositeProp.Name;
        JArray childrenArray = (JArray)compositeProp.Value;
        
        Composite composite = new Composite(compositeName);
        foreach (var childToken in childrenArray)
        {
            Component childComponent;
            var childJObj = (JObject)childToken;
            // 判断是否为Leaf节点:存在experience字段即为Leaf
            if (childJObj.ContainsKey("experience"))
            {
                childComponent = childJObj.ToObject<Leaf>(serializer);
            }
            else
            {
                // 递归反序列化Composite节点
                childComponent = childJObj.ToObject<Composite>(serializer);
            }
            composite.Add(childComponent);
        }
        return composite;
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof(Composite).IsAssignableFrom(objectType);
    }
}

调用示例

// 传入你序列化得到的JSON字符串即可直接反序列化
Composite root = JsonConvert.DeserializeObject<Composite>(yourJsonString);

注意事项

  • 若后续Leaf节点扩展字段,判断Leaf的逻辑可以按需调整,比如改为判断节点没有数组类型的属性即可。
  • 现有逻辑完全适配你当前的序列化输出结构,不需要修改原有类定义和序列化逻辑。

内容的提问来源于stack exchange,提问作者Povilas Dirse

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:36:06