Description
Using the InferClosedTypePolymorphism in preview 7, there seems to be no way to serialize a closed hierarchy that contains multiple closed types?
e.g. given a hierarchy like this:
Pet (closed)
|___ Cat
|___ Dog (closed)
|___ Labrador
|___ Collie
then if you try to serialize a Pet instance you get an exception:
System.InvalidOperationException: Specified type 'Dog' is not a supported
derived type for the polymorphic type 'Pet'. Derived types must not be open
generic type definitions, must be assignable to the base type and cannot be
abstract classes or interfaces unless 'JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor'
is specified.
That seems like a big limitation? 🤔
Reproduction Steps
The following simple program reproduces the issue:
Pet data = new Labrador();
var opts = new JsonSerializerOptions { InferClosedTypePolymorphism = true };
string serialized = JsonSerializer.Serialize(data, opts);
// Type definitions
closed class Pet {}
sealed class Cat : Pet { }
closed class Dog : Pet { }
sealed class Labrador : Dog { }
sealed class Collie : Dog { }
Expected behavior
I would expect that the Pet to recursively know about all it's descendants given it's a closed hierarchy. I can understand that this can't always be possible (if you have unsealed types for example), but in the example above, the hierarchy is completely defined?
Actual behavior
System.InvalidOperationException: Specified type 'Dog' is not a supported
derived type for the polymorphic type 'Pet'. Derived types must not be open
generic type definitions, must be assignable to the base type and cannot be
abstract classes or interfaces unless 'JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor'
is specified.
Regression?
No, this is new functionality
Known Workarounds
I couldn't find a way to make this work with InferClosedTypePolymorphism. The only approach I could find was to fallback to manually specify the derived types on Pet, i.e. manually do what I expected the feature to do
[JsonDerivedType(typeof(Collie), typeDiscriminator: nameof(Collie))]
[JsonDerivedType(typeof(Labrador), typeDiscriminator: nameof(Labrador))]
[JsonDerivedType(typeof(Cat), typeDiscriminator: nameof(Cat))]
public closed class Pet
Configuration
❯ dotnet --version
11.0.100-preview.7.26381.103
Windows 11, x64
Other information
Related to #125449
Description
Using the
InferClosedTypePolymorphismin preview 7, there seems to be no way to serialize a closed hierarchy that contains multipleclosedtypes?e.g. given a hierarchy like this:
then if you try to serialize a
Petinstance you get an exception:That seems like a big limitation? 🤔
Reproduction Steps
The following simple program reproduces the issue:
Expected behavior
I would expect that the Pet to recursively know about all it's descendants given it's a closed hierarchy. I can understand that this can't always be possible (if you have unsealed types for example), but in the example above, the hierarchy is completely defined?
Actual behavior
Regression?
No, this is new functionality
Known Workarounds
I couldn't find a way to make this work with
InferClosedTypePolymorphism. The only approach I could find was to fallback to manually specify the derived types onPet, i.e. manually do what I expected the feature to doConfiguration
Windows 11, x64
Other information
Related to #125449