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

如何反序列化包含多种不同结构子类型对象数组的JSON数据

解决思路

不用定义通用泛型,通过自定义JSON转换器即可实现一次性反序列化,两种常用JSON库的实现方案如下:

方案1:基于Newtonsoft.Json实现

步骤1:补全类的属性映射

首先补全主对象的字段,同时给Parent类的属性加上与JSON字段对应的映射标记:

public class MainObject
{
    public string id { get; set; }
    public string Name { get; set; }
    public IEnumerable<Parent> Parents { get; set; }
}

public class Parent
{
    [JsonProperty("ChildName")]
    public string NameOfChildObjectType { get; set; }
    [JsonProperty("Parameters")]
    public object Child { get; set; }
}

// Child_1、Child_2、Child_3类保持原有定义即可

步骤2:定义类型映射关系

提前建立JSON中类型标识与实际CLR类型的映射字典:

internal static class ChildTypeConfig
{
    public static readonly IReadOnlyDictionary<string, Type> Map = new Dictionary<string, Type>
    {
        {"ChildOfType1", typeof(Child_1)},
        {"ChildOfType2", typeof(Child_2)},
        {"ChildOfType3", typeof(Child_3)}
    };
}

步骤3:实现Parent类的自定义转换器

public class ParentConverter : JsonConverter<Parent>
{
    public override Parent ReadJson(JsonReader reader, Type objectType, Parent existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jsonObj = JObject.Load(reader);
        var parent = new Parent();
        
        // 读取类型标识
        parent.NameOfChildObjectType = jsonObj["ChildName"].Value<string>();
        
        // 匹配对应类型并反序列化Child对象
        if (ChildTypeConfig.Map.TryGetValue(parent.NameOfChildObjectType, out var targetChildType))
        {
            parent.Child = jsonObj["Parameters"].ToObject(targetChildType, serializer);
        }
        else
        {
            // 未匹配到类型时可保留原始JSON节点,或按业务需求抛出异常
            parent.Child = jsonObj["Parameters"];
        }
        return parent;
    }

    // 无需序列化能力可直接省略实现
    public override void WriteJson(JsonWriter writer, Parent value, JsonSerializer serializer)
        => throw new NotImplementedException();
}

步骤4:直接一次性反序列化

反序列化时传入自定义转换器即可:

var deserializeSettings = new JsonSerializerSettings
{
    Converters = { new ParentConverter() }
};
var result = JsonConvert.DeserializeObject<MainObject>(yourJsonString, deserializeSettings);

方案2:基于System.Text.Json实现

逻辑与上述方案完全一致,仅需替换为System.Text.Json对应的特性与Converter基类即可,无需修改核心逻辑。

使用说明

反序列化完成后,可通过类型判断直接操作不同的Child实例:

foreach (var parent in result.Parents)
{
    switch (parent.Child)
    {
        case Child_1 c1:
            // 处理Child_1类型的逻辑
            break;
        case Child_2 c2:
            // 处理Child_2类型的逻辑
            break;
        case Child_3 c3:
            // 处理Child_3类型的逻辑
            break;
    }
}

内容的提问来源于stack exchange,提问作者Michal Cikatricis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:48:04