applejag / Newtonsoft.Json-for-Unity

Newtonsoft.Json (Json.NET) 10.0.3, 11.0.2, 12.0.3, & 13.0.1 for Unity IL2CPP builds, available via Unity Package Manager
https://github.com/jilleJr/Newtonsoft.Json-for-Unity
MIT License
1.15k stars 128 forks source link

Fix Queue/Stack deserializing with IL2CPP #53

Closed applejag closed 2 years ago

applejag commented 4 years ago

Description

As found in @felipegodias issue #51, the Queue<T> type cannot be deserialized in the IL2CPP runtime if not referencing the new Queue<T>(IEnumerable<T>) constructor as Json .NET apparently uses that parameterized constructor for said type.

https://github.com/JamesNK/Newtonsoft.Json/blob/12.0.3/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs#L194-L201

This assumably would also apply to the Stack<T> type. Would have to investigate if the non-generic Queue and Stack also would be fine. Difficult to test non-generic ones as anything that would generate the AOT code will make a test on non-generated AOT code not work properly.

Tricky!

Motivation

Possibility to deserialize Queue and Stack on IL2CPP runtime.

Suggested solution

Three possible solutions:

  1. Add ensuring of the constructor in AotHelper, but that does not help with types inheriting from Queue<T> as it's not possible to ensure other constructors than the default one generically.

  2. Add a custom converter for Queue<> and Stack<> types.

  3. Modify Json .NET to populate queues and stacks via their .Enqueue(T item) and .Push(T item) methods, respectively. Will have to investigate how this can be done with the least amount of changes to the Json .NET code as possible and distinguishable so I don't accidentally remove the fix later.

Nr 2 would be easiest to implement and give the best user experience, except for when users define their own converters. Perhaps hacky to force a converter in there. Which makes option nr 3 the dominating solution, and perhaps the most "best practice"-esque.

applejag commented 3 years ago

This had to be forwarded to 12.0.303 as the changes from #54 were too important to delay further.

applejag commented 2 years ago

I'm closing this as I do not find it prioritized.

If anyone finds this issue while searching for an answer, the I would advice you to serialize a different type instead and only use a Stack or Queue in your deserialized workflows.