Add support for more concrete types & derived types during deserialization.#40668
Add support for more concrete types & derived types during deserialization.#40668CodeBlanch wants to merge 38 commits intodotnet:masterfrom
Conversation
…. Fixed null reference exception being thrown when we don't know how to create a derived enumerable or dictionary type.
…ection & ReadOnlyCollection), derived types, and any type that can accept IList in constructor (must derive from a supported type).
|
FYI @layomia has another PR out there (#40654) also for https://github.com/dotnet/corefx/issues/40597. My approach was to add support for more of the common stuff. |
|
@CodeBlanch, thanks for submitting this PR! I think it should build atop #40654, and subsequent PRs to address https://github.com/dotnet/corefx/issues/40370 and https://github.com/dotnet/corefx/issues/40657. These changes will ensure that all collections in the System.Collections* namespaces are either supported for (de)serialization (if the implementation can fit into the existing (de)serialization logic), or throw a clear One concern that we have with the current (de)serialization logic is that it manages a lot of state which can become unwieldy. This PR adds more state ( The plan for post-3.0 is to refactor collection to support to leverage the converter mechanism where possible and have a cleaner implementation that supports |
…tions in CreateIEnumerableInstance & CreateIDictionaryInstance based in feedback.
|
@layomia Thanks for the link! Some great insight and context I was missing. Agree greatly there's a lot of room for improvement. The array paths were a mess. Adding the new state/flags allowed me to direct a lot of the logic into the existing converters. IMO it gets things into a much nicer state which can then be improved upon further. Pushed some changes...
One thing my initial change does is open up support for derived types that need to be passed an IList or IDictionary during construction. The derived types need only expose a constructor to accept the temp list being built up. I added an exception with an explicit message for those... catch (MissingMethodException)
{
throw ThrowHelper.ThrowNotSupportedException_DeserializeInstanceConstructorNotFound(parentType, sourceList.GetType());
}
catch (MissingMethodException)
{
throw ThrowHelper.ThrowNotSupportedException_DeserializeInstanceConstructorNotFound(parentType, sourceDictionary.GetType());
}What are your thoughts on that? |
…inal instance instead of buffering up a temporary list/dictionary.
Deserialization refactoring
|
@steveharter @layomia I refactored all of the dictionary/collection deserialization code into JsonEnumerableConverters & JsonDictionaryConverters. Should be much faster now, especially on cold startup. A few methods before like GetImplementedCollectionType would be called constantly. I was able to support basically every built-in collection and dictionary type (directly, inherited, or derived) that I could think of, lots of the tests that threw NotSupported now pass. Eliminated IDictionaryConstructible completely. Overall less code paths and complexity to worry about. Anyway if you think this is worthwhile let me know and I'll run performance benchmarks and resolve conflicts with the latest improvements. |
|
Thank you for your contribution. As announced in dotnet/coreclr#27549 this repository will be moving to dotnet/runtime on November 13. If you would like to continue working on this PR after this date, the easiest way to move the change to dotnet/runtime is:
|
|
@CodeBlanch thanks for the PR. Most of the issues it addresses, including extended collection support (Queue, ObservableCollection), the removal of ClassType.IDictionaryConstructible, various null refs, and the repeated calls to The only thing left is the creation of collections using ctors. that take |
|
Closing this PR in light of comments above. |
Adds support for ReadOnlyDictionary<,> concrete type and derived types. Examples that will now work fine:
Right now you will get this nasty NullRef Exception:
Adds supports for Collection<>, ObservableCollection<>, & ReadOnlyCollection<> concrete types and derived types. Examples that will now work fine:
Also enables a bunch of TODO scenarios that were sprinkled around the code. Queue, Stack, HashTable, etc. Some tests that failed with a note to get working in the future now work.
Implementation
It was simple to get this working for Dictionaries. Array code was a totally different story! Way more code paths and mixed up logic. What I did was refactor the Array code to work like the (much cleaner) Dictionary code. IMO it is a bit more maintainable now, has more features, and might even be a smidge faster.
Issues
Resolves https://github.com/dotnet/corefx/issues/40597
Resolves https://github.com/dotnet/corefx/issues/40479
Starts https://github.com/dotnet/corefx/issues/38552