用newtonsoft json问题反序列化列表

时间:2020-05-31 09:25:02

标签: c# json list json.net

我正在用C#学习Newtonsoft JSON库。

我有一个叫做“敌人”的类,它是从“ Ente”类派生的。 我有一个“ Ente”类型的列表。 在此列表中,我添加了“ enemy”类的一些实例并序列化了列表,所有这些都正确。 然后,在列表为空的情况下,我从磁盘读取JSON文件,对其进行反序列化,然后将结果分配给类型为“ Ente”的列表。 所有正确但有敌意的对象都是使用“ Ente”类的构造函数创建的,这是问题所在,应该通过调用“ Enemy”类的构造函数来创建对象,也就是说,对象是“ Enemy”必须创建而不是“ Ente”对象。

**编辑1:

我还有其他类也来自“ Ente”,并且这些实例必须保存在“ EnteList”列表中。 例如,这些是其他源自“ Ente”的类:

敌人:恩特

BallOfFire:Ente

巨魔:Ente

等...

在示例中,我将其简化为最大程度,并认为没有必要提供该信息。 我认为newtonsoft库应该自动执行此操作,因为我指定在序列化时将列表中的对象类型保存在JSON文件中。**

问题是:在反序列化时如何使“敌人”对象构造函数运行?

列表:

public List< Ente > EnteList { get; set; } = new List< Ente >();

代码序列化和反序列化:

        EnteList.Add( new Enemy( ) );
        JsonSerializerSettings setting = new JsonSerializerSettings();
        setting.TypeNameHandling = TypeNameHandling.Objects;
        string json = JsonConvert.SerializeObject( EnteList, Formatting.Indented, setting );
        EnteList.Clear();
        EnteList = JsonConvert.DeserializeObject< List< Ente > >( json );

敌人和敌人类别:

public class Ente
{
    public Ente()
    {
        Console.WriteLine( "\n Constructor of Ente executed" );
    }
}

public class Enemy : Ente
{
    public Enemy()
    {
        Console.WriteLine( "\n Constructor of Enemy executed" );
    }
}

1 个答案:

答案 0 :(得分:0)

已编辑

我了解你。

尝试一下:

class Program
{
    public static List<Ente> EnteList { get; set; } = new List<Ente>();

    static void Main(string[] args)
    {
        EnteList.Add(new Enemy() { EnemyName = "Frodo" });
        EnteList.Add(new Troll() { TrollName = "Bilbo" });
        JsonSerializerSettings setting = new JsonSerializerSettings();
        setting.TypeNameHandling = TypeNameHandling.Objects;
        string json = JsonConvert.SerializeObject(EnteList, Formatting.Indented, setting);
        EnteList.Clear();

        List<Ente> result = JsonConvert.DeserializeObject<List<Ente>>(json, new JsonEnteConverter());

        Console.ReadLine();
    }
}

public class Ente
{
    public virtual string Type { get; set; }

    public Ente()
    {
        Console.WriteLine("\n Constructor of Ente executed");
    }
}

public class Enemy : Ente
{
    public override string Type { get => "Enemy"; }

    public string EnemyName { get; set; }

    public Enemy() 
    {
        Console.WriteLine("\n Constructor of Enemy executed");
    }
}

public class Troll : Ente
{
    public override string Type { get => "Troll"; }

    public string TrollName { get; set; }

    public Troll()
    {
        Console.WriteLine("\n Constructor of Troll executed");
    }
}

public class JsonEnteConverter : Newtonsoft.Json.Converters.CustomCreationConverter<Ente>
{
    public override Ente Create(Type objectType)
    {
        throw new NotImplementedException();
    }

    public Ente Create(JObject jObject)
    {
        var type = jObject.Property("Type").ToString(); //get property Type from your json
        switch (type)
        {
            case "Enemy":
                return new Enemy();
            case "Troll":
                return new Troll();
        }
        throw new ApplicationException(String.Format("Type not found", type));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jObject = JObject.Load(reader);
        var targetObject = Create(jObject); // Create your object based on JObject
        serializer.Populate(jObject.CreateReader(), targetObject);
        return targetObject;
    }
}

最主要的是-您必须编写自定义的JsonConverter

相关问题