private JsonPropertyInfo AddProperty(Type propertyType, PropertyInfo propertyInfo, Type classType, JsonSerializerOptions options)
        {
            JsonPropertyInfo jsonInfo = CreateProperty(propertyType, propertyType, propertyInfo, classType, options);

            // Convert non-immutable dictionary interfaces to concrete types.
            if (propertyType.IsInterface && jsonInfo.ClassType == ClassType.Dictionary)
            {
                JsonClassInfo    elementClassInfo    = jsonInfo.ElementClassInfo;
                JsonPropertyInfo elementPropertyInfo = options.GetJsonPropertyInfoFromClassInfo(elementClassInfo, options);

                Type newPropertyType = elementPropertyInfo.GetDictionaryConcreteType();
                if (propertyType != newPropertyType)
                {
                    jsonInfo = CreateProperty(propertyType, newPropertyType, propertyInfo, classType, options);
                }
            }
            else if (jsonInfo.ClassType == ClassType.Enumerable &&
                     !propertyType.IsArray &&
                     (IsDeserializedByAssigningFromList(propertyType) || IsSetInterface(propertyType)))
            {
                JsonClassInfo    elementClassInfo    = jsonInfo.ElementClassInfo;
                JsonPropertyInfo elementPropertyInfo = options.GetJsonPropertyInfoFromClassInfo(elementClassInfo, options);

                // Get a runtime type for the property. e.g. ISet<T> -> HashSet<T>, ICollection -> List<object>
                // We use the element's JsonPropertyInfo so we can utilize the generic support.
                Type newPropertyType = elementPropertyInfo.GetConcreteType(propertyType);
                if ((propertyType != newPropertyType) && propertyType.IsAssignableFrom(newPropertyType))
                {
                    jsonInfo = CreateProperty(propertyType, newPropertyType, propertyInfo, classType, options);
                }
            }

            return(jsonInfo);
        }
예제 #2
0
        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, or natively supported collection.
            Type implementedType = GetImplementedCollectionType(propertyType);

            if (implementedType != propertyType)
            {
                jsonInfo = CreateProperty(implementedType, implementedType, implementedType, null, typeof(object), options);
            }
            else
            {
                jsonInfo = CreateProperty(propertyType, propertyType, propertyType, propertyInfo, classType, options);
            }

            // Convert non-immutable dictionary interfaces to concrete types.
            if (IsNativelySupportedCollection(propertyType) && implementedType.IsInterface && jsonInfo.ClassType == ClassType.Dictionary)
            {
                JsonClassInfo    elementClassInfo    = jsonInfo.ElementClassInfo;
                JsonPropertyInfo elementPropertyInfo = options.GetJsonPropertyInfoFromClassInfo(elementClassInfo, options);

                Type newPropertyType = elementPropertyInfo.GetDictionaryConcreteType();
                if (implementedType != newPropertyType)
                {
                    jsonInfo = CreateProperty(propertyType, newPropertyType, implementedType, propertyInfo, classType, options);
                }
                else
                {
                    jsonInfo = CreateProperty(propertyType, implementedType, implementedType, propertyInfo, classType, options);
                }
            }
            else if (jsonInfo.ClassType == ClassType.Enumerable &&
                     !implementedType.IsArray &&
                     ((IsDeserializedByAssigningFromList(implementedType) && IsNativelySupportedCollection(propertyType)) || IsSetInterface(implementedType)))
            {
                JsonClassInfo    elementClassInfo    = jsonInfo.ElementClassInfo;
                JsonPropertyInfo elementPropertyInfo = options.GetJsonPropertyInfoFromClassInfo(elementClassInfo, options);

                // Get a runtime type for the implemented property. e.g. ISet<T> -> HashSet<T>, ICollection -> List<object>
                // We use the element's JsonPropertyInfo so we can utilize the generic support.
                Type newPropertyType = elementPropertyInfo.GetConcreteType(implementedType);
                if ((implementedType != newPropertyType) && implementedType.IsAssignableFrom(newPropertyType))
                {
                    jsonInfo = CreateProperty(propertyType, newPropertyType, implementedType, propertyInfo, classType, options);
                }
                else
                {
                    jsonInfo = CreateProperty(propertyType, implementedType, implementedType, propertyInfo, classType, options);
                }
            }
            else if (propertyType != implementedType)
            {
                jsonInfo = CreateProperty(propertyType, implementedType, implementedType, propertyInfo, classType, options);
            }

            return(jsonInfo);
        }