简体   繁体   中英

C# JSON.net NewtonSoft not converting object inheritence correctly

I am trying to serialize and deserialize inheriting objects in a dictionary using JSON.net NewtonSoft.

In my program I have 3 classes setup A , B and C . Both B and C inherit A :

public class A
{
    public virtual string Value { get; } = "string";
}


public class B : A
{
    public override string Value => this.Score.ToString();

    public int Score { get; set; } = 5;
}

public class C : A
{
    public override string Value => this.AnotherScore.ToString();

    public int AnotherScore { get; set; } = 6;
}

In my code I create a dictionary which can story objects inheriting A and fill it with a B and a C object.

When I try using the objects in the dictionary, C# still knows the objects are of their type. (see code below)

But after serializing and deserializing, C# doesn't understand that it has to treat the B and C object in the dictionary as B and C objects.

static void Main(string[] args)
{
    // Create objects to store in dictionary
    B b = new B();
    A c = (A)new C(); 

    // Store objects in dictionary
    var dic = new Dictionary<string, A>();
    dic.Add("b", b);
    dic.Add("c", c);

    // C# still know the objects are of their type
    Console.WriteLine(dic["b"].Value);
    Console.WriteLine(dic["c"].Value);

    // Convert dictionary to JSON
    string serialized = JsonConvert.SerializeObject(dic, new JsonSerializerSettings()
    {
        Formatting = Formatting.Indented,
        PreserveReferencesHandling = PreserveReferencesHandling.Objects,
        TypeNameHandling = TypeNameHandling.Objects,
    });

    Console.WriteLine(serialized);

    // Convert json to dictionary
    var dic2 = JsonConvert.DeserializeObject<Dictionary<string, A>>(serialized);

    // C# doesn't know objects are of their type anymore
    Console.WriteLine(dic2["b"].Value);
    Console.WriteLine(dic2["c"].Value);




    Console.ReadKey();
}

Output:

5
6
{
  "$id": "1",
  "$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[TestConsole.A, TestConsole]], mscorlib",
  "b": {
    "$id": "2",
    "$type": "TestConsole.B, TestConsole",
    "Value": "5",
    "Score": 5
  },
  "c": {
    "$id": "3",
    "$type": "TestConsole.C, TestConsole",
    "Value": "6",
    "AnotherScore": 6
  }
}
string
string

How do I let NewtonSoft know it should serialize the objects correctly with their correct type?

So that the last two write lines will write the same as the first two.

Passing the same settings to the DesirializeObject will solve this issue.

Sorry for bothering.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM