Add polymorphic serialization to System.Text.Json #54328
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #29937. Based on the prototype in #53882 which incorporates #30083. API design pending approval.
Infrastructural Changes
Here is a high-level overview of the infrastructural changes being made:
CanBePolymorphicandCanUseDirectReadOrWriteproperties fromJsonConverterhave been moved toJsonTypeInfo, since the value of these flags can now be influenced by user configuration or attributes.WriteStackstruct to support polymorphism:WriteStack.NextValueCanBePolymorphicproperty which replacesJsonConverter.CanBePolymorphic.ReferenceResolver.IgnoreCyclesimplementation: the current implementation contains bespoke code to avoid polymorphic converters triggering false negatives. I have refactored the code slightly so that the cycle detection logic is combined with the polymorphic serialization infrastructure.Potential breaking change
The changes isolated in b14bcdf introduce a deliberate breaking change when it comes to the handling of
new object()values. The existing implementation will hardcode the serialization to{}even if the user has subscribed a customJsonConverter<object>that does something different. I would like to change this behavior for a few reasons:new object()values. Users cannot specify a custom serialization format fornew object()values.objectinstance serialization to the relevant converter.new object()instances are being serialized in production applications.The breaking change concerns the following scenario:
In .NET 5 the above would print
{}, however under the new changes it would print42. This could break users with custom object converters who rely on the existing hardcoding behavior.Performance
When benchmarked against
mainusing statistical testing with 5% threshold, performance of the feature branch is largely equivalent. It should be noted however that certain polymorphism-heavy scenaria (e.g.WriteJson<ArrayList>) do record a slight regression (which can be observed when applying thresholds < 3%). After profiling the code I can confirm that this regression is in part attributable to the additional work required by computing theWriteStack.NextValueCanBePolymorphicproperty.