如何使用继承/多态性将JSON字符串解析为C#对象 [英] How do I parse a JSON string to a C# object using inheritance / polymorphism
问题描述
我想将JSON字符串解析为可能是多态的C#对象.
I want to parse a JSON string to a C# object that could be polymorph.
总结一下:我不想实例化根对象,但是我想根据JSON输入实例化继承的对象.
To sum it up: I don't want to instantiate the root object, but i want to instantiate the inherited object depending on the JSON input.
这是我使用的C#对象的示例:
Here's an example of the C# objects I use:
public class Module {
public string name;
}
public class Wheel : Module {
public int amount;
public Wheel(string name, int amount) : base(name) {...}
}
public class Break : Module {
public double delay;
public Break(string name, double delay) : base(name) {...}
}
我有这个JSON字符串,它是一个包含两个JSON对象的数组:
And I have this JSON string that is an array containing two JSON objects:
[{
"name":"Wheel",
"amount":4
},{
"name":"Break",
"delay":1.0
}]
我想将此JSON字符串反序列化为C#对象(列表/数组),每个项目都应实例化为子类(Wheel
或Break
),但由于必须打开List
项相同的分母,列表类型必须为Module
.
I want to have this JSON-string deserialized as a C# object (list/array), each item should be instantiated as a subclass (Wheel
or Break
), but since List
items have to be on the same denominator, the list type has to be of type Module
.
推荐答案
如果使用 Newtonsoft JSON库,您可以创建一些自定义转换器,如下所示:
If you use the Newtonsoft JSON Library, you can create some custom converters, as follows:
public class ModuleObjectConverter : JsonCreationConverter<Module>
{
protected override Module Create(Type objectType, JObject jObject)
{
//This is the important part - we can query what json properties are present
//to figure out what type of object to construct and populate
if (FieldExists("amount", jObject)) {
return new Wheel();
} else if (FieldExists("delay", jObject)) {
return new Break();
} else {
return null;
}
}
private bool FieldExists(string fieldName, JObject jObject)
{
return jObject[fieldName] != null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//We don't deal with writing json, generally newtonsoft would make a good job of
//serializing these type of objects without having to use a custom writer anyway
}
}
//Generic converter class - could combine with above class if you're only dealing
//with one inheritance chain, but this way it's reusable
public abstract class JsonCreationConverter<T> : JsonConverter
{
protected abstract T Create(Type objectType, JObject jObject);
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Load JObject from stream
JObject jObject = JObject.Load(reader);
// Create target object based on JObject
T target = Create(objectType, jObject);
// Populate the object properties
serializer.Populate(jObject.CreateReader(), target);
return target;
}
}
然后在反序列化时将这个帮助程序的实例传递给Newtonsoft:
You then pass an instance of this helper to Newtonsoft when deserializing:
var modules = JsonConvert.DeserializeObject<List<Module>>(jsonString, new ModuleObjectConverter());
这篇关于如何使用继承/多态性将JSON字符串解析为C#对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!