C# .NET反序列化含HologramGroup的Hologram列表时程序崩溃,求助
多态JSON反序列化问题修复
问题背景
尝试反序列化包含Hologram及其派生类HologramGroup的列表,逻辑是通过判断JSON对象是否包含holograms属性来区分类型,但运行时程序崩溃。
问题原因
- 转换器类型不匹配:
Hologram类上标记的[JsonConverter(typeof(ArJsonConverter))]与实际转换器类名MyJsonConverter不一致,导致转换器无法被正确识别和应用。 - 无限递归调用:在
ReadJson中直接使用root.ToObject<T>()时,会创建新的默认序列化器,而Hologram类上的转换器标记会让这个新序列化器再次调用当前转换器,引发无限递归,最终导致栈溢出崩溃。
解决方案
1. 修正转换器类型匹配
将Hologram类上的JsonConverter特性改为指向正确的转换器类型:
[JsonConverter(typeof(MyJsonConverter))] public class Hologram { // ... 原有属性 }
2. 修复递归调用问题
在ReadJson方法中,使用传入的serializer参数进行反序列化,确保内部嵌套的Hologram列表能正确应用转换器,同时避免递归循环:
public override Hologram ReadJson(JsonReader reader, Type objectType, Hologram existingValue, bool hasExistingValue, JsonSerializer serializer) { JObject root = JObject.Load(reader); if (root.TryGetValue("holograms", out _)) { // 使用传入的serializer反序列化,保证内部Holograms列表正确转换 return root.ToObject<HologramGroup>(serializer); } return root.ToObject<Hologram>(serializer); }
3. 可选:实现序列化方法(WriteJson)
如果需要支持序列化操作,补充实现WriteJson方法:
public override void WriteJson(JsonWriter writer, Hologram value, JsonSerializer serializer) { JObject obj = value switch { HologramGroup group => JObject.FromObject(group, serializer), _ => JObject.FromObject(value, serializer) }; obj.WriteTo(writer); }
完整修正后代码
转换器代码
public class MyJsonConverter : JsonConverter<Hologram> { public override Hologram ReadJson(JsonReader reader, Type objectType, Hologram existingValue, bool hasExistingValue, JsonSerializer serializer) { JObject root = JObject.Load(reader); if (root.TryGetValue("holograms", out _)) { return root.ToObject<HologramGroup>(serializer); } return root.ToObject<Hologram>(serializer); } public override void WriteJson(JsonWriter writer, Hologram value, JsonSerializer serializer) { JObject obj = value switch { HologramGroup group => JObject.FromObject(group, serializer), _ => JObject.FromObject(value, serializer) }; obj.WriteTo(writer); } }
类定义
[JsonConverter(typeof(MyJsonConverter))] public class Hologram { public string HologramType { get; set; } public List<HologramProperty> Properties { get; set; } } public class HologramGroup : Hologram { public List<Hologram> Holograms { get; set; } } public class Scene { public string Name { get; set; } public List<Hologram> Holograms { get; set; } }
内容的提问来源于stack exchange,提问作者KarlSupertramp
相关产品推荐
相关产品推荐

