Add a JsonConverter.Type property. (#87382)
authorEirik Tsarpalis <eirik.tsarpalis@gmail.com>
Mon, 12 Jun 2023 18:55:10 +0000 (19:55 +0100)
committerGitHub <noreply@github.com>
Mon, 12 Jun 2023 18:55:10 +0000 (19:55 +0100)
34 files changed:
src/libraries/System.Text.Json/ref/System.Text.Json.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/CastingConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IAsyncEnumerableOfTConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ICollectionOfTConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfTKeyTValueConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListOfTConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfTKeyTValueConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ISetOfTConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/JsonCollectionConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/JsonDictionaryConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/StackOrQueueConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverterFactory.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.MetadataHandling.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleMetadata.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/DefaultJsonTypeInfoResolver.Converters.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfoOfT.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs
src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs
src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs
src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.KeyConverters.cs
src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CustomConverterTests/CustomConverterTests.cs

index 7974eb6..bc75757 100644 (file)
@@ -199,6 +199,7 @@ namespace System.Text.Json
     }
     public static partial class JsonSerializer
     {
+        public static bool IsReflectionEnabledByDefault { get { throw null; } }
         public static object? Deserialize(System.IO.Stream utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; }
         [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")]
         [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
@@ -284,7 +285,6 @@ namespace System.Text.Json
         [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
         public static TValue? Deserialize<TValue>(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
         public static TValue? Deserialize<TValue>(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.Serialization.Metadata.JsonTypeInfo<TValue> jsonTypeInfo) { throw null; }
-        public static bool IsReflectionEnabledByDefault { get { throw null; } }
         public static void Serialize(System.IO.Stream utf8Json, object? value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { }
         [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")]
         [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
@@ -395,14 +395,14 @@ namespace System.Text.Json
         public System.Text.Json.Serialization.JsonUnmappedMemberHandling UnmappedMemberHandling { get { throw null; } set { } }
         public bool WriteIndented { get { throw null; } set { } }
         [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
-        [System.ObsoleteAttribute("JsonSerializerOptions.AddContext is obsolete. To register a JsonSerializerContext, use either the TypeInfoResolver or TypeInfoResolverChain properties.", DiagnosticId = "SYSLIB0049", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
+        [System.ObsoleteAttribute("JsonSerializerOptions.AddContext is obsolete. To register a JsonSerializerContext, use either the TypeInfoResolver or TypeInfoResolverChain properties.", DiagnosticId="SYSLIB0049", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
         public void AddContext<TContext>() where TContext : System.Text.Json.Serialization.JsonSerializerContext, new() { }
         [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Getting a converter for a type may require reflection which depends on runtime code generation.")]
         [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Getting a converter for a type may require reflection which depends on unreferenced code.")]
         public System.Text.Json.Serialization.JsonConverter GetConverter(System.Type typeToConvert) { throw null; }
         public System.Text.Json.Serialization.Metadata.JsonTypeInfo GetTypeInfo(System.Type type) { throw null; }
-        public bool TryGetTypeInfo(System.Type type, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { throw null; }
         public void MakeReadOnly() { }
+        public bool TryGetTypeInfo(System.Type type, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.Json.Serialization.Metadata.JsonTypeInfo? typeInfo) { throw null; }
     }
     public enum JsonTokenType : byte
     {
@@ -592,8 +592,8 @@ namespace System.Text.Json
         public void WritePropertyName(System.ReadOnlySpan<char> propertyName) { }
         public void WritePropertyName(string propertyName) { }
         public void WritePropertyName(System.Text.Json.JsonEncodedText propertyName) { }
-        public void WriteRawValue(System.ReadOnlySpan<byte> utf8Json, bool skipInputValidation = false) { }
         public void WriteRawValue(System.Buffers.ReadOnlySequence<byte> utf8Json, bool skipInputValidation = false) { }
+        public void WriteRawValue(System.ReadOnlySpan<byte> utf8Json, bool skipInputValidation = false) { }
         public void WriteRawValue([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Json")] System.ReadOnlySpan<char> json, bool skipInputValidation = false) { }
         public void WriteRawValue([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Json")] string json, bool skipInputValidation = false) { }
         public void WriteStartArray() { }
@@ -884,6 +884,7 @@ namespace System.Text.Json.Serialization
     public abstract partial class JsonConverter
     {
         internal JsonConverter() { }
+        public abstract System.Type? Type { get; }
         public abstract bool CanConvert(System.Type typeToConvert);
     }
     [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Enum | System.AttributeTargets.Field | System.AttributeTargets.Interface | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple=false)]
@@ -898,12 +899,14 @@ namespace System.Text.Json.Serialization
     public abstract partial class JsonConverterFactory : System.Text.Json.Serialization.JsonConverter
     {
         protected JsonConverterFactory() { }
+        public sealed override System.Type? Type { get { throw null; } }
         public abstract System.Text.Json.Serialization.JsonConverter? CreateConverter(System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options);
     }
     public abstract partial class JsonConverter<T> : System.Text.Json.Serialization.JsonConverter
     {
         protected internal JsonConverter() { }
         public virtual bool HandleNull { get { throw null; } }
+        public sealed override System.Type Type { get { throw null; } }
         public override bool CanConvert(System.Type typeToConvert) { throw null; }
         public abstract T? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options);
         public virtual T ReadAsPropertyName(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { throw null; }
@@ -975,7 +978,7 @@ namespace System.Text.Json.Serialization
         Replace = 0,
         Populate = 1,
     }
-    [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
+    [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Field | System.AttributeTargets.Interface | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple=false)]
     public sealed partial class JsonObjectCreationHandlingAttribute : System.Text.Json.Serialization.JsonAttribute
     {
         public JsonObjectCreationHandlingAttribute(System.Text.Json.Serialization.JsonObjectCreationHandling handling) { }
@@ -1229,13 +1232,13 @@ namespace System.Text.Json.Serialization.Metadata
     {
         internal JsonPropertyInfo() { }
         public System.Reflection.ICustomAttributeProvider? AttributeProvider { get { throw null; } set { } }
-        public System.Text.Json.Serialization.JsonObjectCreationHandling? ObjectCreationHandling { get { throw null; } set { } }
         public System.Text.Json.Serialization.JsonConverter? CustomConverter { get { throw null; } set { } }
         public System.Func<object, object?>? Get { get { throw null; } set { } }
         public bool IsExtensionData { get { throw null; } set { } }
         public bool IsRequired { get { throw null; } set { } }
         public string Name { get { throw null; } set { } }
         public System.Text.Json.Serialization.JsonNumberHandling? NumberHandling { get { throw null; } set { } }
+        public System.Text.Json.Serialization.JsonObjectCreationHandling? ObjectCreationHandling { get { throw null; } set { } }
         public System.Text.Json.JsonSerializerOptions Options { get { throw null; } }
         public int Order { get { throw null; } set { } }
         public System.Type PropertyType { get { throw null; } }
@@ -1269,7 +1272,6 @@ namespace System.Text.Json.Serialization.Metadata
         public bool IsReadOnly { get { throw null; } }
         public System.Text.Json.Serialization.Metadata.JsonTypeInfoKind Kind { get { throw null; } }
         public System.Text.Json.Serialization.JsonNumberHandling? NumberHandling { get { throw null; } set { } }
-        public System.Text.Json.Serialization.JsonObjectCreationHandling? PreferredPropertyObjectCreationHandling { get { throw null; } set { } }
         public System.Action<object>? OnDeserialized { get { throw null; } set { } }
         public System.Action<object>? OnDeserializing { get { throw null; } set { } }
         public System.Action<object>? OnSerialized { get { throw null; } set { } }
@@ -1278,6 +1280,7 @@ namespace System.Text.Json.Serialization.Metadata
         [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
         public System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver? OriginatingResolver { get { throw null; } set { } }
         public System.Text.Json.Serialization.Metadata.JsonPolymorphismOptions? PolymorphismOptions { get { throw null; } set { } }
+        public System.Text.Json.Serialization.JsonObjectCreationHandling? PreferredPropertyObjectCreationHandling { get { throw null; } set { } }
         public System.Collections.Generic.IList<System.Text.Json.Serialization.Metadata.JsonPropertyInfo> Properties { get { throw null; } }
         public System.Type Type { get { throw null; } }
         public System.Text.Json.Serialization.JsonUnmappedMemberHandling? UnmappedMemberHandling { get { throw null; } set { } }
index ece6207..f607b62 100644 (file)
@@ -21,7 +21,7 @@ namespace System.Text.Json.Serialization.Converters
 
         internal CastingConverter(JsonConverter sourceConverter)
         {
-            Debug.Assert(typeof(T).IsInSubtypeRelationshipWith(sourceConverter.TypeToConvert));
+            Debug.Assert(typeof(T).IsInSubtypeRelationshipWith(sourceConverter.Type!));
             Debug.Assert(sourceConverter.SourceConverterForCastingConverter is null, "casting converters should not be layered.");
 
             _sourceConverter = sourceConverter;
index d518eb1..2351625 100644 (file)
@@ -16,7 +16,7 @@ namespace System.Text.Json.Serialization.Converters
         {
             if (!typeToConvert.IsAssignableFrom(typeof(IAsyncEnumerable<TElement>)))
             {
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
 
             return base.OnTryRead(ref reader, typeToConvert, options, ref state, out value!);
@@ -37,7 +37,7 @@ namespace System.Text.Json.Serialization.Converters
         {
             if (!state.SupportAsync)
             {
-                ThrowHelper.ThrowNotSupportedException_TypeRequiresAsyncSerialization(TypeToConvert);
+                ThrowHelper.ThrowNotSupportedException_TypeRequiresAsyncSerialization(Type);
             }
 
             return base.OnTryWrite(writer, value, options, ref state);
index 61a1106..662076e 100644 (file)
@@ -33,16 +33,16 @@ namespace System.Text.Json.Serialization.Converters
             if (returnValue.IsReadOnly)
             {
                 state.Current.ReturnValue = null; // clear out for more accurate JsonPath reporting.
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
         }
 
         internal override void ConfigureJsonTypeInfo(JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options)
         {
             // Deserialize as List<T> for interface types that support it.
-            if (jsonTypeInfo.CreateObject is null && TypeToConvert.IsAssignableFrom(typeof(List<TElement>)))
+            if (jsonTypeInfo.CreateObject is null && Type.IsAssignableFrom(typeof(List<TElement>)))
             {
-                Debug.Assert(TypeToConvert.IsInterface);
+                Debug.Assert(Type.IsInterface);
                 jsonTypeInfo.CreateObject = () => new List<TElement>();
             }
         }
index bd86cec..9f8a481 100644 (file)
@@ -35,7 +35,7 @@ namespace System.Text.Json.Serialization.Converters
             if (returnValue.IsReadOnly)
             {
                 state.Current.ReturnValue = null; // clear out for more accurate JsonPath reporting.
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
         }
 
@@ -100,9 +100,9 @@ namespace System.Text.Json.Serialization.Converters
         internal override void ConfigureJsonTypeInfo(JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options)
         {
             // Deserialize as Dictionary<TKey,TValue> for interface types that support it.
-            if (jsonTypeInfo.CreateObject is null && TypeToConvert.IsAssignableFrom(typeof(Dictionary<string, object?>)))
+            if (jsonTypeInfo.CreateObject is null && Type.IsAssignableFrom(typeof(Dictionary<string, object?>)))
             {
-                Debug.Assert(TypeToConvert.IsInterface);
+                Debug.Assert(Type.IsInterface);
                 jsonTypeInfo.CreateObject = () => new Dictionary<string, object?>();
             }
         }
index 635c0eb..fb1a1b6 100644 (file)
@@ -35,16 +35,16 @@ namespace System.Text.Json.Serialization.Converters
             if (returnValue.IsReadOnly)
             {
                 state.Current.ReturnValue = null; // clear out for more accurate JsonPath reporting.
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
         }
 
         internal override void ConfigureJsonTypeInfo(JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options)
         {
             // Deserialize as Dictionary<TKey,TValue> for interface types that support it.
-            if (jsonTypeInfo.CreateObject is null && TypeToConvert.IsAssignableFrom(typeof(Dictionary<TKey, TValue>)))
+            if (jsonTypeInfo.CreateObject is null && Type.IsAssignableFrom(typeof(Dictionary<TKey, TValue>)))
             {
-                Debug.Assert(TypeToConvert.IsInterface);
+                Debug.Assert(Type.IsInterface);
                 jsonTypeInfo.CreateObject = () => new Dictionary<TKey, TValue>();
             }
         }
index 33c6379..767bae4 100644 (file)
@@ -27,7 +27,7 @@ namespace System.Text.Json.Serialization.Converters
         {
             if (!_isDeserializable)
             {
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
 
             state.Current.ReturnValue = new List<object?>();
index 905e721..a0eb21f 100644 (file)
@@ -25,7 +25,7 @@ namespace System.Text.Json.Serialization.Converters
         {
             if (!_isDeserializable)
             {
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
 
             state.Current.ReturnValue = new List<TElement>();
index bbf2df8..aaa8fc9 100644 (file)
@@ -32,7 +32,7 @@ namespace System.Text.Json.Serialization.Converters
             if (returnValue.IsReadOnly)
             {
                 state.Current.ReturnValue = null; // clear out for more accurate JsonPath reporting.
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
         }
 
@@ -79,9 +79,9 @@ namespace System.Text.Json.Serialization.Converters
         internal override void ConfigureJsonTypeInfo(JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options)
         {
             // Deserialize as List<object?> for interface types that support it.
-            if (jsonTypeInfo.CreateObject is null && TypeToConvert.IsAssignableFrom(typeof(List<object?>)))
+            if (jsonTypeInfo.CreateObject is null && Type.IsAssignableFrom(typeof(List<object?>)))
             {
-                Debug.Assert(TypeToConvert.IsInterface);
+                Debug.Assert(Type.IsInterface);
                 jsonTypeInfo.CreateObject = () => new List<object?>();
             }
         }
index 6964905..e55fac2 100644 (file)
@@ -33,16 +33,16 @@ namespace System.Text.Json.Serialization.Converters
             if (returnValue.IsReadOnly)
             {
                 state.Current.ReturnValue = null; // clear out for more accurate JsonPath reporting.
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
         }
 
         internal override void ConfigureJsonTypeInfo(JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options)
         {
             // Deserialize as List<T> for interface types that support it.
-            if (jsonTypeInfo.CreateObject is null && TypeToConvert.IsAssignableFrom(typeof(List<TElement>)))
+            if (jsonTypeInfo.CreateObject is null && Type.IsAssignableFrom(typeof(List<TElement>)))
             {
-                Debug.Assert(TypeToConvert.IsInterface);
+                Debug.Assert(Type.IsInterface);
                 jsonTypeInfo.CreateObject = () => new List<TElement>();
             }
         }
index e42ecfe..236da66 100644 (file)
@@ -23,7 +23,7 @@ namespace System.Text.Json.Serialization.Converters
         {
             if (!_isDeserializable)
             {
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
 
             state.Current.ReturnValue = new Dictionary<TKey, TValue>();
index 2472a68..df6cb00 100644 (file)
@@ -30,16 +30,16 @@ namespace System.Text.Json.Serialization.Converters
             if (returnValue.IsReadOnly)
             {
                 state.Current.ReturnValue = null; // clear out for more accurate JsonPath reporting.
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
         }
 
         internal override void ConfigureJsonTypeInfo(JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options)
         {
             // Deserialize as HashSet<TElement> for interface types that support it.
-            if (jsonTypeInfo.CreateObject is null && TypeToConvert.IsAssignableFrom(typeof(HashSet<TElement>)))
+            if (jsonTypeInfo.CreateObject is null && Type.IsAssignableFrom(typeof(HashSet<TElement>)))
             {
-                Debug.Assert(TypeToConvert.IsInterface);
+                Debug.Assert(Type.IsInterface);
                 jsonTypeInfo.CreateObject = () => new HashSet<TElement>();
             }
         }
index 64969c5..d8ef486 100644 (file)
@@ -37,13 +37,13 @@ namespace System.Text.Json.Serialization
                 // The contract model was not able to produce a default constructor for two possible reasons:
                 // 1. Either the declared collection type is abstract and cannot be instantiated.
                 // 2. The collection type does not specify a default constructor.
-                if (TypeToConvert.IsAbstract || TypeToConvert.IsInterface)
+                if (Type.IsAbstract || Type.IsInterface)
                 {
-                    ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                    ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
                 }
                 else
                 {
-                    ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(TypeToConvert, ref reader, ref state);
+                    ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(Type, ref reader, ref state);
                 }
             }
 
@@ -79,7 +79,7 @@ namespace System.Text.Json.Serialization
 
                 if (reader.TokenType != JsonTokenType.StartArray)
                 {
-                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
+                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type);
                 }
 
                 CreateCollection(ref reader, ref state, options);
@@ -98,7 +98,7 @@ namespace System.Text.Json.Serialization
                         }
 
                         // Obtain the CLR value from the JSON and apply to the object.
-                        TElement? element = elementConverter.Read(ref reader, elementConverter.TypeToConvert, options);
+                        TElement? element = elementConverter.Read(ref reader, elementConverter.Type, options);
                         Add(element!, ref state);
                     }
                 }
@@ -134,14 +134,14 @@ namespace System.Text.Json.Serialization
                     {
                         if (reader.TokenType != JsonTokenType.StartObject)
                         {
-                            ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
+                            ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type);
                         }
 
                         state.Current.ObjectState = StackFrameObjectState.StartToken;
                     }
                     else
                     {
-                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
+                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type);
                     }
 
                     state.Current.JsonPropertyInfo = elementTypeInfo.PropertyInfoForTypeInfo;
@@ -171,7 +171,7 @@ namespace System.Text.Json.Serialization
                     ResolvePolymorphicConverter(jsonTypeInfo, ref state) is JsonConverter polymorphicConverter)
                 {
                     Debug.Assert(!IsValueType);
-                    bool success = polymorphicConverter.OnTryReadAsObject(ref reader, polymorphicConverter.TypeToConvert, options, ref state, out object? objectResult);
+                    bool success = polymorphicConverter.OnTryReadAsObject(ref reader, polymorphicConverter.Type!, options, ref state, out object? objectResult);
                     value = (TCollection)objectResult!;
                     state.ExitPolymorphicConverter(success);
                     return success;
index c91105e..6a50c84 100644 (file)
@@ -52,13 +52,13 @@ namespace System.Text.Json.Serialization
                 // The contract model was not able to produce a default constructor for two possible reasons:
                 // 1. Either the declared collection type is abstract and cannot be instantiated.
                 // 2. The collection type does not specify a default constructor.
-                if (TypeToConvert.IsAbstract || TypeToConvert.IsInterface)
+                if (Type.IsAbstract || Type.IsInterface)
                 {
-                    ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                    ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
                 }
                 else
                 {
-                    ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(TypeToConvert, ref reader, ref state);
+                    ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(Type, ref reader, ref state);
                 }
             }
 
@@ -95,7 +95,7 @@ namespace System.Text.Json.Serialization
 
                 if (reader.TokenType != JsonTokenType.StartObject)
                 {
-                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
+                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type);
                 }
 
                 CreateCollection(ref reader, ref state);
@@ -165,7 +165,7 @@ namespace System.Text.Json.Serialization
                 {
                     if (reader.TokenType != JsonTokenType.StartObject)
                     {
-                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
+                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type);
                     }
 
                     state.Current.ObjectState = StackFrameObjectState.StartToken;
@@ -195,7 +195,7 @@ namespace System.Text.Json.Serialization
                     ResolvePolymorphicConverter(jsonTypeInfo, ref state) is JsonConverter polymorphicConverter)
                 {
                     Debug.Assert(!IsValueType);
-                    bool success = polymorphicConverter.OnTryReadAsObject(ref reader, polymorphicConverter.TypeToConvert, options, ref state, out object? objectResult);
+                    bool success = polymorphicConverter.OnTryReadAsObject(ref reader, polymorphicConverter.Type!, options, ref state, out object? objectResult);
                     value = (TDictionary)objectResult!;
                     state.ExitPolymorphicConverter(success);
                     return success;
@@ -313,13 +313,13 @@ namespace System.Text.Json.Serialization
                 state.Current.JsonPropertyNameAsString = unescapedPropertyNameAsString; // Copy key name for JSON Path support in case of error.
 
                 // Special case string to avoid calling GetString twice and save one allocation.
-                if (keyConverter.IsInternalConverter && keyConverter.TypeToConvert == typeof(string))
+                if (keyConverter.IsInternalConverter && keyConverter.Type == typeof(string))
                 {
                     key = (TKey)(object)unescapedPropertyNameAsString;
                 }
                 else
                 {
-                    key = keyConverter.ReadAsPropertyNameCore(ref reader, keyConverter.TypeToConvert, options);
+                    key = keyConverter.ReadAsPropertyNameCore(ref reader, keyConverter.Type, options);
                 }
 
                 return key;
index e3ed08d..7831bb5 100644 (file)
@@ -32,7 +32,7 @@ namespace System.Text.Json.Serialization.Converters
 
             if (constructorDelegate == null)
             {
-                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(TypeToConvert, ref reader, ref state);
+                ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
             }
 
             state.Current.ReturnValue = constructorDelegate();
index 4b61f2d..8492814 100644 (file)
@@ -18,13 +18,13 @@ namespace System.Text.Json.Serialization.Converters
 
         public sealed override object ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
         {
-            ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(TypeToConvert, this);
+            ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(Type, this);
             return null!;
         }
 
         internal sealed override object ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
         {
-            ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(TypeToConvert, this);
+            ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(Type, this);
             return null!;
         }
 
@@ -53,7 +53,7 @@ namespace System.Text.Json.Serialization.Converters
             }
 
             Type runtimeType = value.GetType();
-            if (runtimeType == TypeToConvert)
+            if (runtimeType == Type)
             {
                 ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(runtimeType, this);
             }
index 36f9126..90b3e09 100644 (file)
@@ -29,7 +29,7 @@ namespace System.Text.Json.Serialization.Converters
 
                 if (reader.TokenType != JsonTokenType.StartObject)
                 {
-                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
+                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type);
                 }
 
                 if (state.ParentProperty?.TryGetPrePopulatedValue(ref state) == true)
@@ -59,7 +59,7 @@ namespace System.Text.Json.Serialization.Converters
                 {
                     if (reader.TokenType != JsonTokenType.StartObject)
                     {
-                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
+                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type);
                     }
 
                     state.Current.ObjectState = StackFrameObjectState.StartToken;
@@ -89,7 +89,7 @@ namespace System.Text.Json.Serialization.Converters
                     ResolvePolymorphicConverter(jsonTypeInfo, ref state) is JsonConverter polymorphicConverter)
                 {
                     Debug.Assert(!IsValueType);
-                    bool success = polymorphicConverter.OnTryReadAsObject(ref reader, polymorphicConverter.TypeToConvert, options, ref state, out object? objectResult);
+                    bool success = polymorphicConverter.OnTryReadAsObject(ref reader, polymorphicConverter.Type!, options, ref state, out object? objectResult);
                     value = (T)objectResult!;
                     state.ExitPolymorphicConverter(success);
                     return success;
index db3c164..53be31a 100644 (file)
@@ -42,7 +42,7 @@ namespace System.Text.Json.Serialization.Converters
 
                 if (reader.TokenType != JsonTokenType.StartObject)
                 {
-                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
+                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type);
                 }
 
                 if (state.ParentProperty?.TryGetPrePopulatedValue(ref state) == true)
@@ -117,7 +117,7 @@ namespace System.Text.Json.Serialization.Converters
                 {
                     if (reader.TokenType != JsonTokenType.StartObject)
                     {
-                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
+                        ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type);
                     }
 
                     state.Current.ObjectState = StackFrameObjectState.StartToken;
@@ -147,7 +147,7 @@ namespace System.Text.Json.Serialization.Converters
                     ResolvePolymorphicConverter(jsonTypeInfo, ref state) is JsonConverter polymorphicConverter)
                 {
                     Debug.Assert(!IsValueType);
-                    bool success = polymorphicConverter.OnTryReadAsObject(ref reader, polymorphicConverter.TypeToConvert, options, ref state, out object? objectResult);
+                    bool success = polymorphicConverter.OnTryReadAsObject(ref reader, polymorphicConverter.Type!, options, ref state, out object? objectResult);
                     value = (T)objectResult!;
                     state.ExitPolymorphicConverter(success);
                     return success;
@@ -569,7 +569,7 @@ namespace System.Text.Json.Serialization.Converters
 
             if (jsonTypeInfo.ParameterCount != jsonTypeInfo.ParameterCache!.Count)
             {
-                ThrowHelper.ThrowInvalidOperationException_ConstructorParameterIncompleteBinding(TypeToConvert);
+                ThrowHelper.ThrowInvalidOperationException_ConstructorParameterIncompleteBinding(Type);
             }
 
             state.Current.InitializeRequiredPropertiesValidationState(jsonTypeInfo);
index 08d3e37..4e23121 100644 (file)
@@ -65,8 +65,8 @@ namespace System.Text.Json.Serialization.Converters
             string[] names = Enum.GetNames<T>();
             T[] values = Enum.GetValues<T>();
 #else
-            string[] names = Enum.GetNames(TypeToConvert);
-            Array values = Enum.GetValues(TypeToConvert);
+            string[] names = Enum.GetNames(Type);
+            Array values = Enum.GetValues(Type);
 #endif
             Debug.Assert(names.Length == values.Length);
 
index 53aa155..f645443 100644 (file)
@@ -24,7 +24,7 @@ namespace System.Text.Json.Serialization.Converters
             JsonConverter valueConverter = options.GetConverterInternal(valueTypeToConvert);
 
             // If the value type has an interface or object converter, just return that converter directly.
-            if (!valueConverter.TypeToConvert.IsValueType && valueTypeToConvert.IsValueType)
+            if (!valueConverter.Type!.IsValueType && valueTypeToConvert.IsValueType)
             {
                 return valueConverter;
             }
index 13b7dad..96e02f3 100644 (file)
@@ -30,7 +30,7 @@ namespace System.Text.Json.Serialization
                     PolymorphicTypeResolver resolver = jsonTypeInfo.PolymorphicTypeResolver;
                     if (resolver.TryGetDerivedJsonTypeInfo(state.PolymorphicTypeDiscriminator, out JsonTypeInfo? resolvedType))
                     {
-                        Debug.Assert(TypeToConvert.IsAssignableFrom(resolvedType.Type));
+                        Debug.Assert(Type!.IsAssignableFrom(resolvedType.Type));
 
                         polymorphicConverter = state.InitializePolymorphicReEntry(resolvedType);
                         if (!polymorphicConverter.CanHaveMetadata)
@@ -48,7 +48,7 @@ namespace System.Text.Json.Serialization
 
                 case PolymorphicSerializationState.PolymorphicReEntrySuspended:
                     polymorphicConverter = state.ResumePolymorphicReEntry();
-                    Debug.Assert(TypeToConvert.IsAssignableFrom(polymorphicConverter.TypeToConvert));
+                    Debug.Assert(Type!.IsAssignableFrom(polymorphicConverter.Type));
                     break;
 
                 case PolymorphicSerializationState.PolymorphicReEntryNotFound:
@@ -69,7 +69,7 @@ namespace System.Text.Json.Serialization
         internal JsonConverter? ResolvePolymorphicConverter(object value, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options, ref WriteStack state)
         {
             Debug.Assert(!IsValueType);
-            Debug.Assert(value != null && TypeToConvert.IsAssignableFrom(value.GetType()));
+            Debug.Assert(value != null && Type!.IsAssignableFrom(value.GetType()));
             Debug.Assert(CanBePolymorphic || jsonTypeInfo.PolymorphicTypeResolver != null);
             Debug.Assert(state.PolymorphicTypeDiscriminator is null);
 
@@ -82,9 +82,9 @@ namespace System.Text.Json.Serialization
 
                     Type runtimeType = value.GetType();
 
-                    if (CanBePolymorphic && runtimeType != TypeToConvert)
+                    if (CanBePolymorphic && runtimeType != Type)
                     {
-                        Debug.Assert(TypeToConvert == typeof(object));
+                        Debug.Assert(Type == typeof(object));
                         jsonTypeInfo = state.Current.InitializePolymorphicReEntry(runtimeType, options);
                         polymorphicConverter = jsonTypeInfo.Converter;
                     }
@@ -120,7 +120,7 @@ namespace System.Text.Json.Serialization
                 case PolymorphicSerializationState.PolymorphicReEntrySuspended:
                     Debug.Assert(state.IsContinuation);
                     polymorphicConverter = state.Current.ResumePolymorphicReEntry();
-                    Debug.Assert(TypeToConvert.IsAssignableFrom(polymorphicConverter.TypeToConvert));
+                    Debug.Assert(Type.IsAssignableFrom(polymorphicConverter.Type));
                     break;
 
                 case PolymorphicSerializationState.PolymorphicReEntryNotFound:
index 54d2561..1acdf4b 100644 (file)
@@ -21,6 +21,15 @@ namespace System.Text.Json.Serialization
         }
 
         /// <summary>
+        /// Gets the type being converted by the current converter instance.
+        /// </summary>
+        /// <remarks>
+        /// For instances of type <see cref="JsonConverter{T}"/> returns typeof(T),
+        /// and for instances of type <see cref="JsonConverterFactory"/> returns <see langword="null" />.
+        /// </remarks>
+        public abstract Type? Type { get; }
+
+        /// <summary>
         /// Determines whether the type can be converted.
         /// </summary>
         /// <param name="typeToConvert">The type is checked as to whether it can be converted.</param>
@@ -168,9 +177,6 @@ namespace System.Text.Json.Serialization
             return (state.FlushThreshold > 0 && writer.BytesPending > state.FlushThreshold);
         }
 
-        // This is used internally to quickly determine the type being converted for JsonConverter<T>.
-        internal abstract Type TypeToConvert { get; }
-
         internal abstract object? ReadAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options);
         internal abstract bool OnTryReadAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, scoped ref ReadStack state, out object? value);
         internal abstract bool TryReadAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, scoped ref ReadStack state, out object? value);
index 4ac5516..973d369 100644 (file)
@@ -22,9 +22,9 @@ namespace System.Text.Json.Serialization
         private protected override ConverterStrategy GetDefaultConverterStrategy() => ConverterStrategy.None;
 
         /// <summary>
-        /// Create a converter for the provided <see cref="Type"/>.
+        /// Create a converter for the provided <see cref="System.Type"/>.
         /// </summary>
-        /// <param name="typeToConvert">The <see cref="Type"/> being converted.</param>
+        /// <param name="typeToConvert">The <see cref="System.Type"/> being converted.</param>
         /// <param name="options">The <see cref="JsonSerializerOptions"/> being used.</param>
         /// <returns>
         /// An instance of a <see cref="JsonConverter{T}"/> where T is compatible with <paramref name="typeToConvert"/>.
@@ -142,7 +142,7 @@ namespace System.Text.Json.Serialization
             throw new InvalidOperationException();
         }
 
-        internal sealed override Type TypeToConvert => null!;
+        public sealed override Type? Type => null;
 
         internal sealed override void WriteAsPropertyNameCoreAsObject(
             Utf8JsonWriter writer,
index 34265f4..490d834 100644 (file)
@@ -11,7 +11,7 @@ namespace System.Text.Json.Serialization
     /// <summary>
     /// Converts an object or value to or from JSON.
     /// </summary>
-    /// <typeparam name="T">The <see cref="Type"/> to convert.</typeparam>
+    /// <typeparam name="T">The <see cref="System.Type"/> to convert.</typeparam>
     public abstract partial class JsonConverter<T> : JsonConverter
     {
         /// <summary>
@@ -143,7 +143,7 @@ namespace System.Text.Json.Serialization
         /// A converter may throw any Exception, but should throw <cref>JsonException</cref> when the JSON is invalid.
         /// </remarks>
         /// <param name="reader">The <see cref="Utf8JsonReader"/> to read from.</param>
-        /// <param name="typeToConvert">The <see cref="Type"/> being converted.</param>
+        /// <param name="typeToConvert">The <see cref="System.Type"/> being converted.</param>
         /// <param name="options">The <see cref="JsonSerializerOptions"/> being used.</param>
         /// <returns>The value that was converted.</returns>
         /// <remarks>Note that the value of <seealso cref="HandleNull"/> determines if the converter handles null JSON tokens.</remarks>
@@ -156,7 +156,7 @@ namespace System.Text.Json.Serialization
             {
                 if (default(T) is not null)
                 {
-                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(TypeToConvert);
+                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type);
                 }
 
                 value = default;
@@ -236,7 +236,7 @@ namespace System.Text.Json.Serialization
             JsonTypeInfo originalJsonTypeInfo = state.Current.JsonTypeInfo;
 #endif
             state.Push();
-            Debug.Assert(TypeToConvert == state.Current.JsonTypeInfo.Type);
+            Debug.Assert(Type == state.Current.JsonTypeInfo.Type);
 
 #if DEBUG
             // For performance, only perform validation on internal converters on debug builds.
@@ -380,7 +380,7 @@ namespace System.Text.Json.Serialization
                 state.Current.PolymorphicSerializationState != PolymorphicSerializationState.PolymorphicReEntryStarted)
             {
                 JsonTypeInfo jsonTypeInfo = state.PeekNestedJsonTypeInfo();
-                Debug.Assert(jsonTypeInfo.Converter.TypeToConvert == TypeToConvert);
+                Debug.Assert(jsonTypeInfo.Converter.Type == Type);
 
                 bool canBePolymorphic = CanBePolymorphic || jsonTypeInfo.PolymorphicTypeResolver is not null;
                 JsonConverter? polymorphicConverter = canBePolymorphic ?
@@ -417,7 +417,7 @@ namespace System.Text.Json.Serialization
             JsonTypeInfo originalJsonTypeInfo = state.Current.JsonTypeInfo;
 #endif
             state.Push();
-            Debug.Assert(TypeToConvert == state.Current.JsonTypeInfo.Type);
+            Debug.Assert(Type == state.Current.JsonTypeInfo.Type);
 
 #if DEBUG
             // For performance, only perform validation on internal converters on debug builds.
@@ -463,7 +463,7 @@ namespace System.Text.Json.Serialization
             {
                 // If not JsonDictionaryConverter<T> then we are JsonObject.
                 // Avoid a type reference to JsonObject and its converter to support trimming.
-                Debug.Assert(TypeToConvert == typeof(Nodes.JsonObject));
+                Debug.Assert(Type == typeof(Nodes.JsonObject));
                 return TryWrite(writer, value, options, ref state);
             }
 
@@ -498,7 +498,7 @@ namespace System.Text.Json.Serialization
             return success;
         }
 
-        internal sealed override Type TypeToConvert { get; } = typeof(T);
+        public sealed override Type Type { get; } = typeof(T);
 
         internal void VerifyRead(JsonTokenType tokenType, int depth, long bytesConsumed, bool isValueConverter, ref Utf8JsonReader reader)
         {
@@ -584,7 +584,7 @@ namespace System.Text.Json.Serialization
         /// Reads a dictionary key from a JSON property name.
         /// </summary>
         /// <param name="reader">The <see cref="Utf8JsonReader"/> to read from.</param>
-        /// <param name="typeToConvert">The <see cref="Type"/> being converted.</param>
+        /// <param name="typeToConvert">The <see cref="System.Type"/> being converted.</param>
         /// <param name="options">The <see cref="JsonSerializerOptions"/> being used.</param>
         /// <returns>The value that was converted.</returns>
         /// <remarks>Method should be overridden in custom converters of types used in deserialized dictionary keys.</remarks>
@@ -594,7 +594,7 @@ namespace System.Text.Json.Serialization
             JsonConverter<T>? fallbackConverter = GetFallbackConverterForPropertyNameSerialization(options);
             if (fallbackConverter is null)
             {
-                ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(TypeToConvert, this);
+                ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(Type, this);
             }
 
             return fallbackConverter.ReadAsPropertyNameCore(ref reader, typeToConvert, options);
@@ -627,7 +627,7 @@ namespace System.Text.Json.Serialization
             JsonConverter<T>? fallbackConverter = GetFallbackConverterForPropertyNameSerialization(options);
             if (fallbackConverter is null)
             {
-                ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(TypeToConvert, this);
+                ThrowHelper.ThrowNotSupportedException_DictionaryKeyTypeNotSupported(Type, this);
             }
 
             fallbackConverter.WriteAsPropertyNameCore(writer, value, options, isWritingExtensionDataProperty: false);
@@ -644,7 +644,7 @@ namespace System.Text.Json.Serialization
             {
                 // Extension data is meant as mechanism to gather unused JSON properties;
                 // do not apply any custom key conversions and hardcode the default behavior.
-                Debug.Assert(!IsInternalConverter && TypeToConvert == typeof(string));
+                Debug.Assert(!IsInternalConverter && Type == typeof(string));
                 writer.WritePropertyName((string)(object)value!);
                 return;
             }
@@ -668,7 +668,7 @@ namespace System.Text.Json.Serialization
             {
                 result = _fallbackConverterForPropertyNameSerialization;
 
-                if (result is null && DefaultJsonTypeInfoResolver.TryGetDefaultSimpleConverter(TypeToConvert, out JsonConverter? defaultConverter))
+                if (result is null && DefaultJsonTypeInfoResolver.TryGetDefaultSimpleConverter(Type, out JsonConverter? defaultConverter))
                 {
                     Debug.Assert(defaultConverter != this);
                     _fallbackConverterForPropertyNameSerialization = result = (JsonConverter<T>)defaultConverter;
index c9a9e60..df11d95 100644 (file)
@@ -75,7 +75,7 @@ namespace System.Text.Json
                             if (!converter.CanHaveMetadata)
                             {
                                 // Should not be permitted unless the converter is capable of handling metadata.
-                                ThrowHelper.ThrowJsonException_MetadataCannotParsePreservedObjectIntoImmutable(converter.TypeToConvert);
+                                ThrowHelper.ThrowJsonException_MetadataCannotParsePreservedObjectIntoImmutable(converter.Type!);
                             }
 
                             break;
@@ -91,7 +91,7 @@ namespace System.Text.Json
                             if (converter.IsValueType)
                             {
                                 // Should not be permitted if the converter is a struct.
-                                ThrowHelper.ThrowJsonException_MetadataInvalidReferenceToValueType(converter.TypeToConvert);
+                                ThrowHelper.ThrowJsonException_MetadataInvalidReferenceToValueType(converter.Type!);
                             }
                             if (state.Current.MetadataPropertyNames != 0)
                             {
@@ -446,14 +446,14 @@ namespace System.Text.Json
                     if (state.Current.MetadataPropertyNames != MetadataPropertyName.Ref)
                     {
                         // Read the entire JSON object while parsing for metadata: for collection converters this is only legal for $ref nodes.
-                        ThrowHelper.ThrowJsonException_MetadataPreservedArrayValuesNotFound(ref state, converter.TypeToConvert);
+                        ThrowHelper.ThrowJsonException_MetadataPreservedArrayValuesNotFound(ref state, converter.Type!);
                     }
                     break;
 
                 default:
                     Debug.Assert(reader.TokenType == JsonTokenType.PropertyName);
                     // Do not tolerate non-metadata properties in collection converters.
-                    ThrowHelper.ThrowJsonException_MetadataInvalidPropertyInArrayMetadata(ref state, converter.TypeToConvert, reader);
+                    ThrowHelper.ThrowJsonException_MetadataInvalidPropertyInArrayMetadata(ref state, converter.Type!, reader);
                     break;
             }
         }
index b6c5019..da2cc4c 100644 (file)
@@ -102,7 +102,7 @@ namespace System.Text.Json
             // We also throw to avoid passing an invalid argument to setters for nullable struct properties,
             // which would cause an InvalidProgramException when the generated IL is invoked.
             if (propertyType.IsValueType && converter.IsValueType &&
-                (propertyType.IsNullableOfT() ^ converter.TypeToConvert.IsNullableOfT()))
+                (propertyType.IsNullableOfT() ^ converter.Type!.IsNullableOfT()))
             {
                 ThrowHelper.ThrowInvalidOperationException_ConverterCanConvertMultipleTypes(propertyType, converter);
             }
index 4210d66..9a74546 100644 (file)
@@ -47,10 +47,10 @@ namespace System.Text.Json.Serialization
         }
 
         /// <inheritdoc />
-        public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(TEnum);
+        public sealed override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(TEnum);
 
         /// <inheritdoc />
-        public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
+        public sealed override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
         {
             if (typeToConvert != typeof(TEnum))
             {
index b19fdbc..3ff45ab 100644 (file)
@@ -78,7 +78,7 @@ namespace System.Text.Json.Serialization.Metadata
             return converters;
 
             void Add(JsonConverter converter) =>
-                converters.Add(converter.TypeToConvert, converter);
+                converters.Add(converter.Type!, converter);
         }
 
         private static JsonConverter GetBuiltInConverter(Type typeToConvert)
@@ -154,7 +154,7 @@ namespace System.Text.Json.Serialization.Metadata
 
             // Expand if factory converter & validate.
             converter = options.ExpandConverterFactory(converter, typeToConvert);
-            if (!converter.TypeToConvert.IsInSubtypeRelationshipWith(typeToConvert))
+            if (!converter.Type!.IsInSubtypeRelationshipWith(typeToConvert))
             {
                 ThrowHelper.ThrowInvalidOperationException_SerializationConverterNotCompatible(converter.GetType(), typeToConvert);
             }
index fdc15ca..6c2807a 100644 (file)
@@ -266,10 +266,10 @@ namespace System.Text.Json.Serialization.Metadata
                     if (default(T) is null)
                     {
                         Debug.Assert(CanDeserialize || EffectiveObjectCreationHandling == JsonObjectCreationHandling.Populate);
-                        ThrowHelper.ThrowInvalidOperationException_DeserializeUnableToAssignNull(EffectiveConverter.TypeToConvert);
+                        ThrowHelper.ThrowInvalidOperationException_DeserializeUnableToAssignNull(EffectiveConverter.Type);
                     }
 
-                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(EffectiveConverter.TypeToConvert);
+                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(EffectiveConverter.Type);
                 }
 
                 if (!IgnoreNullTokensOnRead)
@@ -335,7 +335,7 @@ namespace System.Text.Json.Serialization.Metadata
             {
                 if (default(T) is not null)
                 {
-                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(EffectiveConverter.TypeToConvert);
+                    ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(EffectiveConverter.Type);
                 }
 
                 value = default(T);
index 7000de5..9183096 100644 (file)
@@ -920,7 +920,7 @@ namespace System.Text.Json.Serialization.Metadata
         {
             JsonTypeInfo jsonTypeInfo;
 
-            if (converter.TypeToConvert == type)
+            if (converter.Type == type)
             {
                 // For performance, avoid doing a reflection-based instantiation
                 // if the converter type matches that of the declared type.
index adc9b6d..0995171 100644 (file)
@@ -362,7 +362,7 @@ namespace System.Text.Json
         [DoesNotReturn]
         public static void ThrowInvalidOperationException_ConverterCanConvertMultipleTypes(Type runtimePropertyType, JsonConverter jsonConverter)
         {
-            throw new InvalidOperationException(SR.Format(SR.ConverterCanConvertMultipleTypes, jsonConverter.GetType(), jsonConverter.TypeToConvert, runtimePropertyType));
+            throw new InvalidOperationException(SR.Format(SR.ConverterCanConvertMultipleTypes, jsonConverter.GetType(), jsonConverter.Type, runtimePropertyType));
         }
 
         [DoesNotReturn]
index aae3ab1..24e73e4 100644 (file)
@@ -403,10 +403,8 @@ namespace System.Text.Json.SourceGeneration.Tests
         {
             JsonConverter obj = JsonMetadataServices.BooleanConverter;
 
-            string json = JsonSerializer.Serialize(obj, PublicContext.Default.Options);
-            Assert.Equal("{}", json);
-
-            Assert.Throws<NotSupportedException>(() => JsonSerializer.Deserialize<JsonConverter>(json, PublicContext.Default.Options));
+            Assert.Throws<NotSupportedException>(() => JsonSerializer.Serialize(obj, PublicContext.Default.Options));
+            Assert.Throws<NotSupportedException>(() => JsonSerializer.Deserialize<JsonConverter>("{}", PublicContext.Default.Options));
         }
 
         [Fact]
index 7f3f0de..e310a23 100644 (file)
@@ -71,7 +71,7 @@ namespace System.Text.Json.Serialization.Tests
         [InlineData(InvalidCustomKeyConverter.InvalidOperationType.HandleEntireProperty)]
         public static void InvalidCustomKeyConverter_Serialization(InvalidCustomKeyConverter.InvalidOperationType invalidOperationType)
         {
-            var options = new JsonSerializerOptions { Converters = { new InvalidCustomKeyConverter { Type = invalidOperationType } } };
+            var options = new JsonSerializerOptions { Converters = { new InvalidCustomKeyConverter { OperationType = invalidOperationType } } };
             var value = new Dictionary<string, int> { ["key"] = 42 };
 
             Assert.Throws<JsonException>(() => JsonSerializer.Serialize(value, options));
@@ -83,7 +83,7 @@ namespace System.Text.Json.Serialization.Tests
         [InlineData(InvalidCustomKeyConverter.InvalidOperationType.ReturnNull, typeof(ArgumentNullException))]
         public static void InvalidCustomKeyConverter_Deserialization(InvalidCustomKeyConverter.InvalidOperationType invalidOperationType, Type exceptionType)
         {
-            var options = new JsonSerializerOptions { Converters = { new InvalidCustomKeyConverter { Type = invalidOperationType } } };
+            var options = new JsonSerializerOptions { Converters = { new InvalidCustomKeyConverter { OperationType = invalidOperationType } } };
             string json = @"{""key1"" : 1, ""key2"" : 2 }";
 
             Assert.Throws(exceptionType, () => JsonSerializer.Deserialize<Dictionary<string, int>>(json, options));
@@ -111,7 +111,7 @@ namespace System.Text.Json.Serialization.Tests
                 DoNothing, HandleEntireProperty, HandleEntireParentObject, ReturnNull
             }
 
-            public InvalidOperationType Type { get; init; }
+            public InvalidOperationType OperationType { get; init; }
 
             public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
                 => throw new NotSupportedException();
@@ -120,7 +120,7 @@ namespace System.Text.Json.Serialization.Tests
 
             public override void WriteAsPropertyName(Utf8JsonWriter writer, string value, JsonSerializerOptions _)
             {
-                switch (Type)
+                switch (OperationType)
                 {
                     case InvalidOperationType.HandleEntireProperty:
                         writer.WriteString("key", value);
@@ -138,7 +138,7 @@ namespace System.Text.Json.Serialization.Tests
 
             public override string ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions _)
             {
-                switch (Type)
+                switch (OperationType)
                 {
                     case InvalidOperationType.HandleEntireProperty:
                         reader.Read();
index fd85163..42fdc35 100644 (file)
@@ -1,7 +1,7 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System.Diagnostics;
+using System.Collections.Generic;
 using System.IO;
 using Microsoft.DotNet.RemoteExecutor;
 using Xunit;
@@ -241,5 +241,35 @@ namespace System.Text.Json.Serialization.Tests
             public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
                 => new MyBoolEnumConverter();
         }
+
+        [Theory]
+        [InlineData(typeof(ConverterReturningNull), typeof(Customer))]
+        [InlineData(typeof(TestFactory.SimpleConverter), typeof(string))]
+        [InlineData(typeof(ObjectBoolConverter), typeof(object))]
+        [InlineData(typeof(Int32NullConverter), typeof(int))]
+        [InlineData(typeof(JsonStringEnumConverter), null)]
+        [InlineData(typeof(JsonStringEnumConverter<MyBoolEnum>), null)]
+        [InlineData(typeof(InvalidJsonConverterFactory), null)]
+        [InlineData(typeof(TestFactory), null)]
+        public static void JsonConverter_TypeProperty_ReturnsExpectedResult(Type converterType, Type expectedType)
+        {
+            var converter = (JsonConverter)Activator.CreateInstance(converterType)!;
+            Assert.Equal(expectedType, converter.Type);
+        }
+
+        [Theory]
+        [InlineData(typeof(bool))]
+        [InlineData(typeof(int))]
+        [InlineData(typeof(string))]
+        [InlineData(typeof(object))]
+        [InlineData(typeof(MyBoolEnum))]
+        [InlineData(typeof(Customer))]
+        [InlineData(typeof(int[]))]
+        [InlineData(typeof(Dictionary<string, int>))]
+        public static void JsonSerializerOptions_GetConverter_TypeProperty_ReturnsExpectedResult(Type type)
+        {
+            JsonConverter converter = JsonSerializerOptions.Default.GetConverter(type);
+            Assert.Equal(type, converter.Type);
+        }
     }
 }