diff --git a/src/System.Text.Json/src/System.Text.Json.csproj b/src/System.Text.Json/src/System.Text.Json.csproj
index 23b7672de0bc..d111d0060ef3 100644
--- a/src/System.Text.Json/src/System.Text.Json.csproj
+++ b/src/System.Text.Json/src/System.Text.Json.csproj
@@ -50,11 +50,7 @@
-
-
-
-
@@ -89,7 +85,6 @@
-
diff --git a/src/System.Text.Json/src/System/Text/Json/Serialization/ClassType.cs b/src/System.Text.Json/src/System/Text/Json/Serialization/ClassType.cs
index 843d370c089c..e4dad76cb6ac 100644
--- a/src/System.Text.Json/src/System/Text/Json/Serialization/ClassType.cs
+++ b/src/System.Text.Json/src/System/Text/Json/Serialization/ClassType.cs
@@ -23,8 +23,5 @@ internal enum ClassType : byte
Enumerable = 0x8,
// IDictionary
Dictionary = 0x10,
- // Is deserialized by passing a IDictionary to its constructor
- // i.e. immutable dictionaries, Hashtable, SortedList,
- IDictionaryConstructible = 0x20,
}
}
diff --git a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultDerivedDictionaryConverter.cs b/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultDerivedDictionaryConverter.cs
deleted file mode 100644
index f70199c1fd2b..000000000000
--- a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultDerivedDictionaryConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections;
-
-namespace System.Text.Json.Serialization.Converters
-{
- internal sealed class DefaultDerivedDictionaryConverter : JsonDictionaryConverter
- {
- public override object CreateFromDictionary(ref ReadStack state, IDictionary sourceDictionary, JsonSerializerOptions options)
- {
- JsonPropertyInfo collectionPropertyInfo = state.Current.JsonPropertyInfo;
- JsonPropertyInfo elementPropertyInfo = options.GetJsonPropertyInfoFromClassInfo(collectionPropertyInfo.ElementType, options);
- return elementPropertyInfo.CreateDerivedDictionaryInstance(ref state, collectionPropertyInfo, sourceDictionary);
- }
- }
-}
diff --git a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultDerivedEnumerableConverter.cs b/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultDerivedEnumerableConverter.cs
deleted file mode 100644
index 21a05105fc41..000000000000
--- a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultDerivedEnumerableConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections;
-
-namespace System.Text.Json.Serialization.Converters
-{
- internal sealed class DefaultDerivedEnumerableConverter : JsonEnumerableConverter
- {
- public override IEnumerable CreateFromList(ref ReadStack state, IList sourceList, JsonSerializerOptions options)
- {
- JsonPropertyInfo collectionPropertyInfo = state.Current.JsonPropertyInfo;
- JsonPropertyInfo elementPropertyInfo = options.GetJsonPropertyInfoFromClassInfo(collectionPropertyInfo.ElementType, options);
- return elementPropertyInfo.CreateDerivedEnumerableInstance(ref state, collectionPropertyInfo, sourceList);
- }
- }
-}
diff --git a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultICollectionConverter.cs b/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultICollectionConverter.cs
deleted file mode 100644
index 46b6bb33ece9..000000000000
--- a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultICollectionConverter.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections;
-
-namespace System.Text.Json.Serialization.Converters
-{
- internal sealed class DefaultICollectionConverter : JsonEnumerableConverter
- {
- public override IEnumerable CreateFromList(ref ReadStack state, IList sourceList, JsonSerializerOptions options)
- {
- Type enumerableType = state.Current.JsonPropertyInfo.RuntimePropertyType;
- Type elementType = state.Current.JsonPropertyInfo.ElementType;
- JsonPropertyInfo propertyInfo = options.GetJsonPropertyInfoFromClassInfo(elementType, options);
- return propertyInfo.CreateIEnumerableInstance(ref state, enumerableType, sourceList);
- }
- }
-}
diff --git a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultIDictionaryConverter.cs b/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultIDictionaryConverter.cs
deleted file mode 100644
index 2ad5acdb50ca..000000000000
--- a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultIDictionaryConverter.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections;
-
-namespace System.Text.Json.Serialization.Converters
-{
- internal sealed class DefaultIDictionaryConverter : JsonDictionaryConverter
- {
- public override object CreateFromDictionary(ref ReadStack state, IDictionary sourceDictionary, JsonSerializerOptions options)
- {
- Type dictionaryType = state.Current.JsonPropertyInfo.RuntimePropertyType;
- Type elementType = state.Current.JsonPropertyInfo.ElementType;
- JsonPropertyInfo propertyInfo = options.GetJsonPropertyInfoFromClassInfo(elementType, options);
- return propertyInfo.CreateIDictionaryInstance(ref state, dictionaryType, sourceDictionary);
- }
- }
-}
diff --git a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableDictionaryConverter.cs b/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableDictionaryConverter.cs
index 357a9682170f..3ec77b536347 100644
--- a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableDictionaryConverter.cs
+++ b/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableDictionaryConverter.cs
@@ -59,11 +59,14 @@ public static bool IsImmutableDictionary(Type type)
public override object CreateFromDictionary(ref ReadStack state, IDictionary sourceDictionary, JsonSerializerOptions options)
{
Type immutableCollectionType = state.Current.JsonPropertyInfo.RuntimePropertyType;
- Type elementType = state.Current.GetElementType();
+
+ JsonClassInfo elementClassInfo = state.Current.JsonPropertyInfo.ElementClassInfo;
+ Type elementType = elementClassInfo.Type;
string delegateKey = DefaultImmutableEnumerableConverter.GetDelegateKey(immutableCollectionType, elementType, out _, out _);
- JsonPropertyInfo propertyInfo = options.GetJsonPropertyInfoFromClassInfo(elementType, options);
+ JsonPropertyInfo propertyInfo = elementClassInfo.PolicyProperty ?? elementClassInfo.CreateRootObject(options);
+ Debug.Assert(propertyInfo != null);
return propertyInfo.CreateImmutableDictionaryInstance(ref state, immutableCollectionType, delegateKey, sourceDictionary, options);
}
}
diff --git a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableEnumerableConverter.cs b/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableEnumerableConverter.cs
index b774ea9d6c07..296d542fc3a4 100644
--- a/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableEnumerableConverter.cs
+++ b/src/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableEnumerableConverter.cs
@@ -102,14 +102,47 @@ public static void RegisterImmutableCollection(Type immutableCollectionType, Typ
options.TryAddCreateRangeDelegate(delegateKey, createRangeDelegate);
}
+ public static bool IsImmutableEnumerable(Type type, out bool IsImmutableArray)
+ {
+ if (!type.IsGenericType)
+ {
+ IsImmutableArray = false;
+ return false;
+ }
+
+ switch (type.GetGenericTypeDefinition().FullName)
+ {
+ case ImmutableArrayGenericTypeName:
+ IsImmutableArray = true;
+ return true;
+ case ImmutableListGenericTypeName:
+ case ImmutableListGenericInterfaceTypeName:
+ case ImmutableStackGenericTypeName:
+ case ImmutableStackGenericInterfaceTypeName:
+ case ImmutableQueueGenericTypeName:
+ case ImmutableQueueGenericInterfaceTypeName:
+ case ImmutableSortedSetGenericTypeName:
+ case ImmutableHashSetGenericTypeName:
+ case ImmutableSetGenericInterfaceTypeName:
+ IsImmutableArray = false;
+ return true;
+ default:
+ IsImmutableArray = false;
+ return false;
+ }
+ }
+
public override IEnumerable CreateFromList(ref ReadStack state, IList sourceList, JsonSerializerOptions options)
{
Type immutableCollectionType = state.Current.JsonPropertyInfo.RuntimePropertyType;
- Type elementType = state.Current.GetElementType();
+
+ JsonClassInfo elementClassInfo = state.Current.JsonPropertyInfo.ElementClassInfo;
+ Type elementType = elementClassInfo.Type;
string delegateKey = GetDelegateKey(immutableCollectionType, elementType, out _, out _);
- JsonPropertyInfo propertyInfo = options.GetJsonPropertyInfoFromClassInfo(elementType, options);
+ JsonPropertyInfo propertyInfo = elementClassInfo.PolicyProperty ?? elementClassInfo.CreateRootObject(options);
+ Debug.Assert(propertyInfo != null);
return propertyInfo.CreateImmutableCollectionInstance(ref state, immutableCollectionType, delegateKey, sourceList, options);
}
}
diff --git a/src/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.AddProperty.cs b/src/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.AddProperty.cs
index c71d9b568de9..4ba60eb069d7 100644
--- a/src/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.AddProperty.cs
+++ b/src/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.AddProperty.cs
@@ -10,131 +10,64 @@ namespace System.Text.Json
{
internal partial class JsonClassInfo
{
- private void AddPolicyProperty(Type propertyType, JsonSerializerOptions options)
+ private JsonPropertyInfo AddProperty(Type propertyType, PropertyInfo propertyInfo, Type parentClassType, JsonSerializerOptions options)
{
- // A policy property is not a real property on a type; instead it leverages the existing converter
- // logic and generic support to avoid boxing. It is used with values types and elements from collections and
- // dictionaries. Typically it would represent a CLR type such as System.String.
- PolicyProperty = AddProperty(
- propertyType,
- propertyInfo : null, // Not a real property so this is null.
- classType : typeof(object), // A dummy type (not used).
- options : options);
- }
-
- private JsonPropertyInfo AddProperty(Type propertyType, PropertyInfo propertyInfo, Type classType, JsonSerializerOptions options)
- {
- JsonPropertyInfo jsonInfo;
-
- // Get implemented type, if applicable.
- // Will return the propertyType itself if it's a non-enumerable, string, natively supported collection,
- // or if a custom converter has been provided for the type.
- Type implementedType = GetImplementedCollectionType(classType, propertyType, propertyInfo, out JsonConverter converter, options);
-
- if (implementedType != propertyType)
- {
- jsonInfo = CreateProperty(implementedType, implementedType, implementedType, propertyInfo, typeof(object), converter, options);
- }
- else
- {
- jsonInfo = CreateProperty(propertyType, propertyType, propertyType, propertyInfo, classType, converter, options);
- }
-
- // Convert non-immutable dictionary interfaces to concrete types.
- if (IsNativelySupportedCollection(propertyType) && implementedType.IsInterface && jsonInfo.ClassType == ClassType.Dictionary)
+ bool hasIgnoreAttribute = (JsonPropertyInfo.GetAttribute(propertyInfo) != null);
+ if (hasIgnoreAttribute)
{
- JsonPropertyInfo elementPropertyInfo = options.GetJsonPropertyInfoFromClassInfo(jsonInfo.ElementType, options);
-
- Type newPropertyType = elementPropertyInfo.GetDictionaryConcreteType();
- if (implementedType != newPropertyType)
- {
- jsonInfo = CreateProperty(propertyType, newPropertyType, implementedType, propertyInfo, classType, converter, options);
- }
- else
- {
- jsonInfo = CreateProperty(propertyType, implementedType, implementedType, propertyInfo, classType, converter, options);
- }
+ return JsonPropertyInfo.CreateIgnoredPropertyPlaceholder(propertyInfo, options);
}
- else if (jsonInfo.ClassType == ClassType.Enumerable &&
- !implementedType.IsArray &&
- ((IsDeserializedByAssigningFromList(implementedType) && IsNativelySupportedCollection(propertyType)) || IsSetInterface(implementedType)))
- {
- JsonPropertyInfo elementPropertyInfo = options.GetJsonPropertyInfoFromClassInfo(jsonInfo.ElementType, options);
- // Get a runtime type for the implemented property. e.g. ISet -> HashSet, ICollection -> List