【问题标题】:Deserialize JSON to subclasses将 JSON 反序列化为子类
【发布时间】:2014-08-08 13:55:04
【问题描述】:

我有 3 个课程:

class Person {
    public bool IsFemale { get; set; }
}

class Female : Person {
    public string FemaleSpecificProperty { get; set; }
}

class Male: Person { 
    public string MaleSpecificProperty { get; set; }
}

如何根据 Person.IsFemale 属性的值将给定的 JSON 字符串反序列化为特定实例(FemaleMale)? (预先我不知道使用了哪种确切类型,并且该属性是唯一的指示)

我曾考虑聘用 CustomCreationConverter<T>,但不知道如何在这里工作。

【问题讨论】:

标签: c# json.net


【解决方案1】:

这是您的 person 类的转换器。它获取IsFemale 字段值,并基于它创建FemaleMale 人,由序列化程序填充:

public class PersonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(Person).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType,
        object existingValue, JsonSerializer serializer)
    {
        JObject jObject = JObject.Load(reader);
        var isFemale = (bool)jObject["IsFemale"];
        Person target = isFemale ? (Person)new Female() : new Male();
        serializer.Populate(jObject.CreateReader(), target);
        return target;
    }

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

用法:

List<Person> people = new List<Person>
{
    new Male { IsFemale = false, MaleSpecificProperty = "Y" },
    new Male { IsFemale = false, MaleSpecificProperty = "Y" },
    new Female { IsFemale = true, FemaleSpecificProperty = "X" }
};

string json = JsonConvert.SerializeObject(people);
var result = 
     JsonConvert.DeserializeObject<List<Person>>(json, new PersonConverter());

还可以看看 alex 提出的问题:How to implement custom JsonConverter

【讨论】:

  • 另一个问题是 Person 类似乎需要公共默认构造函数,否则转换器可能会尝试使用空参数调用现有构造函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多