NicolaiM
NicolaiM

Reputation: 67

Deserialize object[] with known types

lets say we have an object[] like this:

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

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

I can easily serialize that

string json = JsonConvert.SerializeObject(data);

but if i deserialize it

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

Then deserializedData[0] which initially was of type "int" becomes "long", deserializedData[2] which initially was of type "MyClass" becomes a JObject.

Is there a way to tell the deserializer what object types to expect at each index of the object[]?

I'm not interested in creating a wrapper class for serialization/deserialization. I need to know if it is possible to predefine the "type structure" of the object[] when we already know the structure.

Upvotes: 3

Views: 904

Answers (2)

Nkosi
Nkosi

Reputation: 247163

Json.Net also makes use of dynamic objects, which can be used to infer the type when accessing each index of the 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);

    }
}

Output:

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

Upvotes: 2

dbc
dbc

Reputation: 116805

You could load the JSON into a temporary JArray, then zip it with the original array and deserialize each item with ToObject(), taking the item type from the original array:

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

Sample fiddle.

Upvotes: 1

Related Questions