var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json));
// Copy the reader struct by value to avoid advancing the `reader`
var peakCopy = reader;
Assert.True(peakCopy.Read());
// Start reading the object
Assert.Equal(JsonTokenType.StartObject, peakCopy.TokenType);
Assert.True(peakCopy.Read());
Assert.Equal(JsonTokenType.PropertyName, peakCopy.TokenType);
// Peak the property name
var propertyName = peakCopy.GetString();
if (propertyName == "$type")
{
// Assign the input ref to the peak
reader = peakCopy;
// Read the type value
Assert.True(reader.Read());
Assert.Equal(JsonTokenType.String, reader.TokenType);
var typeName = reader.GetString();
// Read the remaining properties for the descendent type here...
}
else if (propertyName != null)
{
// Read the remaining properties for the descendent type here...
var element = JsonElement.ParseValue(ref reader);
// Get the $type property
if (!element.TryGetProperty("$type", out var typeName))
{
throw new JsonException("Missing $type property.");
}
// Deserialize the `element` as the desired type
}
PoC: