使用已知类型反序列化object []

时间:2016-10-19 23:05:54

标签: c# json serialization json.net deserialization

假设我们有一个像这样的对象:

int Num = 3;
string Str = "test";
MyClass Obj = new MyClass();

object[] data = new object[] {Num, Str, Obj};

我可以轻松地序列化

string json = JsonConvert.SerializeObject(data);

但如果我反序列化

object[] deserializedData = JsonConvert.DeserializeObject<object[]>(json);

然后最初为“int”类型的deserializedData [0]变为“long”, 最初为“MyClass”类型的deserializedData [2]成为一个JObject。

有没有办法告诉反序列化器在对象[]的每个索引处期望哪些对象类型?

我对创建序列化/反序列化的包装类不感兴趣。当我们已经知道结构时,我需要知道是否有可能预定义对象[]的“类型结构”。

2 个答案:

答案 0 :(得分:1)

您可以将JSON加载到临时JArray中,然后将zip加载到原始数组中,并使用ToObject()反序列化每个项目,从原始数组中获取项目类型:

        var deserializedData = JArray.Parse(json)
            .Zip(data, (t, o) => (o == null ? t.ToObject<object>() : t.ToObject(o.GetType())))
            .ToArray();

示例fiddle

答案 1 :(得分:1)

Json.Net还使用动态对象,可以在访问object[]

的每个索引时用于推断类型
using System;
using Newtonsoft.Json;      


public class Program
{
    public class MyClass{ public string Property {get;set;}}

    public static void Main()
    {

        int Num = 3;
        string Str = "test";
        MyClass Obj = new MyClass() { Property = "Hellow World"};

        object[] data = new object[] {Num, Str, Obj};

        string json = JsonConvert.SerializeObject(data);

        Console.WriteLine("Serialized Object: ");       
        Console.WriteLine(json);

        dynamic deserializedData = JsonConvert.DeserializeObject(json);

        int Num2 = deserializedData[0];
        string Str2 = deserializedData[1];
        MyClass Obj2 = deserializedData[2].ToObject<MyClass>();

        Console.WriteLine();
        Console.WriteLine("Deserialized Values: ");     
        Console.WriteLine("Num: {0} - {1} Equal: {2}",Num,Num2,Num==Num2);
        Console.WriteLine("Str: {0} - {1} Equal: {2}",Str,Str2,Str==Str2);
        Console.WriteLine("Obj: {0} - {1} Equal: {2}",Obj,Obj2,Obj.Property==Obj2.Property);

    }
}

输出:

Serialized Object: 
[3,"test",{"Property":"Hellow World"}]

Deserialized Values: 
Num: 3 - 3 Equal: True
Str: test - test Equal: True
Obj: Program+MyClass - Program+MyClass Equal: True