internal sealed override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, ref ReadStack state, [MaybeNullWhen(false)] out T value) { JsonTypeInfo jsonTypeInfo = state.Current.JsonTypeInfo; if (jsonTypeInfo.CreateObject != null) { // Contract customization: fall back to default object converter if user has set a default constructor delegate. return(base.OnTryRead(ref reader, typeToConvert, options, ref state, out value)); } object obj; ArgumentState argumentState = state.Current.CtorArgumentState !; if (!state.SupportContinuation && !state.Current.CanContainMetadata) { // Fast path that avoids maintaining state variables. if (reader.TokenType != JsonTokenType.StartObject) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert); } ReadOnlySpan <byte> originalSpan = reader.OriginalSpan; ReadConstructorArguments(ref state, ref reader, options); obj = (T)CreateObject(ref state.Current); jsonTypeInfo.OnDeserializing?.Invoke(obj); if (argumentState.FoundPropertyCount > 0) { Utf8JsonReader tempReader; FoundProperty[]? properties = argumentState.FoundProperties; Debug.Assert(properties != null); for (int i = 0; i < argumentState.FoundPropertyCount; i++) { JsonPropertyInfo jsonPropertyInfo = properties[i].Item1; long resumptionByteIndex = properties[i].Item3; byte[]? propertyNameArray = properties[i].Item4; string?dataExtKey = properties[i].Item5; tempReader = new Utf8JsonReader( originalSpan.Slice(checked ((int)resumptionByteIndex)), isFinalBlock: true, state: properties[i].Item2); Debug.Assert(tempReader.TokenType == JsonTokenType.PropertyName); state.Current.JsonPropertyName = propertyNameArray; state.Current.JsonPropertyInfo = jsonPropertyInfo; state.Current.NumberHandling = jsonPropertyInfo.EffectiveNumberHandling; bool useExtensionProperty = dataExtKey != null; if (useExtensionProperty) { Debug.Assert(jsonPropertyInfo == state.Current.JsonTypeInfo.ExtensionDataProperty); state.Current.JsonPropertyNameAsString = dataExtKey; JsonSerializer.CreateExtensionDataProperty(obj, jsonPropertyInfo, options); } ReadPropertyValue(obj, ref state, ref tempReader, jsonPropertyInfo, useExtensionProperty); } FoundProperty[] toReturn = argumentState.FoundProperties !; argumentState.FoundProperties = null; ArrayPool <FoundProperty> .Shared.Return(toReturn, clearArray: true); } } else { // Slower path that supports continuation and metadata reads. if (state.Current.ObjectState == StackFrameObjectState.None) { if (reader.TokenType != JsonTokenType.StartObject) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert); } state.Current.ObjectState = StackFrameObjectState.StartToken; } // Read any metadata properties. if (state.Current.CanContainMetadata && state.Current.ObjectState < StackFrameObjectState.ReadMetadata) { if (!JsonSerializer.TryReadMetadata(this, jsonTypeInfo, ref reader, ref state)) { value = default; return(false); } if (state.Current.MetadataPropertyNames == MetadataPropertyName.Ref) { value = JsonSerializer.ResolveReferenceId <T>(ref state); return(true); } state.Current.ObjectState = StackFrameObjectState.ReadMetadata; } // Dispatch to any polymorphic converters: should always be entered regardless of ObjectState progress if (state.Current.MetadataPropertyNames.HasFlag(MetadataPropertyName.Type) && state.Current.PolymorphicSerializationState != PolymorphicSerializationState.PolymorphicReEntryStarted && ResolvePolymorphicConverter(jsonTypeInfo, options, ref state) is JsonConverter polymorphicConverter) { Debug.Assert(!IsValueType); bool success = polymorphicConverter.OnTryReadAsObject(ref reader, options, ref state, out object?objectResult); value = (T)objectResult !; state.ExitPolymorphicConverter(success); return(success); } // Handle metadata post polymorphic dispatch if (state.Current.ObjectState < StackFrameObjectState.ConstructorArguments) { if (state.Current.CanContainMetadata) { JsonSerializer.ValidateMetadataForObjectConverter(this, ref reader, ref state); } if (state.Current.MetadataPropertyNames == MetadataPropertyName.Ref) { value = JsonSerializer.ResolveReferenceId <T>(ref state); return(true); } BeginRead(ref state, ref reader, options); state.Current.ObjectState = StackFrameObjectState.ConstructorArguments; } if (!ReadConstructorArgumentsWithContinuation(ref state, ref reader, options)) { value = default; return(false); } obj = (T)CreateObject(ref state.Current); if (state.Current.MetadataPropertyNames.HasFlag(MetadataPropertyName.Id)) { Debug.Assert(state.ReferenceId != null); Debug.Assert(options.ReferenceHandlingStrategy == ReferenceHandlingStrategy.Preserve); state.ReferenceResolver.AddReference(state.ReferenceId, obj); state.ReferenceId = null; } jsonTypeInfo.OnDeserializing?.Invoke(obj); if (argumentState.FoundPropertyCount > 0) { for (int i = 0; i < argumentState.FoundPropertyCount; i++) { JsonPropertyInfo jsonPropertyInfo = argumentState.FoundPropertiesAsync ![i].Item1;