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

如何使用Json.NET序列化反序列化多态列表并保留对象继承类型

解决方案

你遇到的问题本质是Newtonsoft.Json默认不会在序列化时记录对象的实际类型信息,反序列化时只会按照你指定的List<Location>的元素类型Location构造实例,自然丢失了子类的属性和重写逻辑。可以通过两种方式解决:


方法1:使用内置的TypeNameHandling配置(最简单)

在序列化和反序列化时都指定TypeNameHandling参数,框架会自动给多态对象增加$type元字段记录实际类型,反序列化时自动恢复对应的子类实例。

序列化代码修改

File.WriteAllText(@"serialized.json", JsonConvert.SerializeObject(locations, 
    new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.Auto
    }));

TypeNameHandling.Auto只会在声明类型和实际类型不一致时写入类型信息,不会产生冗余数据。

反序列化代码修改

var stuff = JsonConvert.DeserializeObject<List<Location>>(File.ReadAllText("serialized.json"),
    new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.Auto
    });

方法2:自定义JsonConverter(更安全,适合不可信JSON来源)

如果你的JSON文件来自外部不可信来源,TypeNameHandling存在反序列化攻击风险,你可以手动写转换器判断类型:

public class LocationConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Location);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        // 子类独有的flag字段作为判断依据
        if (jo.ContainsKey("flag"))
        {
            return jo.ToObject<FlaggedLocation>(serializer);
        }
        return jo.ToObject<Location>(serializer);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

反序列化时传入转换器即可,不需要修改序列化逻辑:

var stuff = JsonConvert.DeserializeObject<List<Location>>(File.ReadAllText("serialized.json"),
    new LocationConverter());

额外注意

你贴的代码里存在几处语法错误,需要先修正才能正常运行:

  • FlaggedLocation构造函数调用父类构造时,缺少了List<string> adjacents参数,你测试代码里实例化Location、FlaggedLocation时也漏传了该参数
  • FlaggedLocation的GetAppropriateText重写方法里,AlternateEntrytext拼写和属性定义的AlternateEntryText大小写不一致,else分支也缺少return关键字

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:18:01