如何使用继承/多态性将JSON字符串解析为C#对象? [英] How do I parse a JSON string to a C# object using inheritance / polymorphism?

查看:139
本文介绍了如何使用继承/多态性将JSON字符串解析为C#对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将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#对象(列表/数组).每个项目都应实例化为子类(WheelBreak),但是由于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 content, and 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆