C# .NET - 将派生类反序列化为它的 Base 列表

问题描述 投票:0回答:2

我正在尝试从 json 文件反序列化全息图列表。全息图列表可以包含全息图组,它是全息图的派生类。我正在尝试使用 JsonConverter 来执行此操作。我想检查全息图是否包含属性“全息图”。如果是这种情况,则此 Hologram 应作为 HologramGroup 返回。

转换器:

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 var type))
            {
                return root.ToObject<HologramGroup>();
            }

            return root.ToObject<Hologram>();
        }

        public override void WriteJson(JsonWriter writer, Hologram value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }

课程:

    [JsonConverter(typeof(ArJsonConverter))] //<- Im hoping to use the converter for all Holograms in my JSON. Not sure if this is the right approach.
    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; }
    }

JSON反序列化:

{
  "name": "MyScene",
  "holograms": [
    {
      "hologramType": "Video",    
      "properties": []
    },
    {
      "hologramType": "Picture",    
      "properties": []
    },
    {
      "hologramType": "HologramGroup",    
      "properties": [],
      "holograms": [
        {
          "hologramType": "Model3D",        
          "properties": []
        },
        {
          "hologramType": "Model3D",        
          "properties": []
        }     
      ]
    }
  ]
}

此代码使我的应用程序崩溃,我不太清楚为什么。多态性对我来说很新,我需要一些帮助。

c# json .net polymorphism deserialization
2个回答
1
投票

试试这个:

[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; }
}

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 var _))
        {
            HologramGroup group = new HologramGroup();
            serializer.Populate(root.CreateReader(), group);
            return group;
        }

        Hologram hologram = new Hologram();
        serializer.Populate(root.CreateReader(), hologram);
        return hologram;
    }

    public override void WriteJson(JsonWriter writer, Hologram value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

0
投票

如果你添加一个构造函数,你不需要任何转换器

public class Scene
{
    public string name { get; set; }
    public List<Hologram> holograms { get; set; }

    public Scene(JArray holograms)
    {
    this.holograms = holograms.Select(ho => (string)ho["hologramType"] == "HologramGroup"
                                                ? ho.ToObject<HologramGroup>()
                                                : ho.ToObject<Hologram>()
                                                ).ToList();
    }
}

或者如果您更喜欢转换器

public class Scene
{
    public string name { get; set; }

    [JsonConverter(typeof(GroupConverter))]
    public List<Hologram> holograms { get; set; }
}
public class GroupConverter : JsonConverter<List<Hologram>>
{
    public override List<Hologram> ReadJson(JsonReader reader, Type objectType, List<Hologram> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var holograms = JArray.Load(reader);

        return holograms.Select(ho => (string)ho["hologramType"] == "HologramGroup"
                                                     ? ho.ToObject<HologramGroup>()
                                                     : ho.ToObject<Hologram>()
                                                     ).ToList();
    }

    public override void WriteJson(JsonWriter writer, List<Hologram> value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.