我有一个JSON,我想反序列化为一个类A
;字段之一是抽象类B
的数组(它有一些具体的实现)。是否可以正确反序列化抽象类数组而无需构建自定义JsonConverter?理想情况下,是JSON.net本身而不冗长的内容,例如与TypeNameHandling.All
...在一起,但是我没有那条特别的路线上班。
我确实没有在序列化时访问JSON(如果这样做的话,TypeNameHandling
会很好用),但是只能在反序列化时访问。
具体来说:
public class A // the top-level class to deserialize
{
public B[] arr;
// other members...
}
public abstract class B
{
// ...some fields...
}
public class C : B
{
// a concrete implementation of B
}
public class D : B
{
// another concrete implementation of B
}
我收到的JSON可能类似于:
{
"arr" : [
{
// a C object
},
{
// a D object
}
]
}
我知道您可以使用下面的XML反序列化来有效地干净地做类似的事情;我正在寻找与JSON类似的东西。
// tells the deserializer to deserialize the object with field name "C" as a
// class C, and field name "D" as a D
[XmlElement("C", Type = typeof(C))]
[XmlElement("D", Type = typeof(D))]
public B[] arr;
答案 0 :(得分:0)
由于您无法修改JSON以使用TypeNameHandling
,因此需要创建一个自定义转换器,该转换器检查属性以确定返回哪种类型。假设您的派生类如下所示:
public class C : B
{
public string CProperty { get; set; }
}
public class D : B
{
public string DProperty { get; set; }
}
您可以拥有一个如下所示的自定义转换器类:
public class BConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type type,
object value, JsonSerializer serializer)
{
JObject jobject = JObject.Load(reader);
if (jobject.ContainsKey("CProperty"))
{
return jobject.ToObject<C>(serializer);
}
if (jobject.ContainsKey("DProperty"))
{
return jobject.ToObject<D>(serializer);
}
throw new Exception("Um, this is some other type!");
}
public override bool CanConvert(Type type) => type == typeof(B);
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
=> throw new NotImplementedException();
}
现在您可以像这样反序列化:
var result = JsonConvert.DeserializeObject<A>(json, new BConverter());