private static IDictionary CreateImmutableDictionaryFromTempValues(ref ReadStack state, JsonSerializerOptions options) { Debug.Assert(state.Current.IsProcessingImmutableDictionary); DefaultImmutableConverter converter = (DefaultImmutableConverter)state.Current.JsonPropertyInfo.EnumerableConverter; Debug.Assert(converter != null); return(converter.CreateFromDictionary(ref state, state.Current.TempDictionaryValues, options)); }
// Creates an IEnumerable<TRuntimePropertyType> and populates it with the items in the // sourceList argument then uses the delegateKey argument to identify the appropriate cached // CreateRange<TRuntimePropertyType> method to create and return the desired immutable collection type. public override IDictionary CreateImmutableCollectionFromDictionary(Type collectionType, string delegateKey, IDictionary sourceDictionary, string propertyPath) { if (!DefaultImmutableConverter.TryGetCreateRangeDelegate(delegateKey, out object createRangeDelegateObj)) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(collectionType, propertyPath); } DefaultImmutableConverter.ImmutableDictCreateRangeDelegate <string, TRuntimeProperty> createRangeDelegate = ( (DefaultImmutableConverter.ImmutableDictCreateRangeDelegate <string, TRuntimeProperty>)createRangeDelegateObj); return((IDictionary)createRangeDelegate.Invoke(CreateGenericIEnumerableFromDictionary(sourceDictionary))); }
internal static ClassType GetClassType(Type type) { Debug.Assert(type != null); if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { type = Nullable.GetUnderlyingType(type); } if (DefaultConverters.IsValueConvertable(type)) { return(ClassType.Value); } if (DefaultImmutableConverter.TypeIsImmutableDictionary(type)) { return(ClassType.ImmutableDictionary); } if (typeof(IDictionary).IsAssignableFrom(type) || (type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(IDictionary <,>) || type.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary <,>)))) { return(ClassType.Dictionary); } if (typeof(IEnumerable).IsAssignableFrom(type)) { return(ClassType.Enumerable); } if (type == typeof(object)) { return(ClassType.Unknown); } return(ClassType.Object); }
private void DetermineSerializationCapabilities() { if (ClassType != ClassType.Enumerable && ClassType != ClassType.Dictionary && ClassType != ClassType.ImmutableDictionary) { // We serialize if there is a getter + not ignoring readonly properties. ShouldSerialize = HasGetter && (HasSetter || !Options.IgnoreReadOnlyProperties); // We deserialize if there is a setter. ShouldDeserialize = HasSetter; } else { if (HasGetter) { if (HasSetter) { ShouldDeserialize = true; } else if (!RuntimePropertyType.IsArray && (typeof(IList).IsAssignableFrom(RuntimePropertyType) || typeof(IDictionary).IsAssignableFrom(RuntimePropertyType))) { ShouldDeserialize = true; } } //else if (HasSetter) //{ // // todo: Special case where there is no getter but a setter (and an EnumerableConverter) //} if (ShouldDeserialize) { ShouldSerialize = HasGetter; if (RuntimePropertyType.IsArray) { EnumerableConverter = s_jsonArrayConverter; } else if (ClassType == ClassType.ImmutableDictionary) { DefaultImmutableConverter.RegisterImmutableDictionary( RuntimePropertyType, JsonClassInfo.GetElementType(RuntimePropertyType, parentType: null, memberInfo: null), Options); EnumerableConverter = s_jsonImmutableConverter; } else if (typeof(IEnumerable).IsAssignableFrom(RuntimePropertyType)) { Type elementType = JsonClassInfo.GetElementType(RuntimePropertyType, ParentClassType, PropertyInfo); // If the property type only has interface(s) exposed by JsonEnumerableT<T> then use JsonEnumerableT as the converter. if (RuntimePropertyType.IsAssignableFrom(typeof(JsonEnumerableT <>).MakeGenericType(elementType))) { EnumerableConverter = s_jsonEnumerableConverter; } // Else if IList can't be assigned from the property type (we populate and return an IList directly) // and the type can be constructed with an IEnumerable<T>, then use the // IEnumerableConstructible converter to create the instance. else if (!typeof(IList).IsAssignableFrom(RuntimePropertyType) && RuntimePropertyType.GetConstructor(new Type[] { typeof(List <>).MakeGenericType(elementType) }) != null) { EnumerableConverter = s_jsonIEnumerableConstuctibleConverter; } // Else if it's a System.Collections.Immutable type with one generic argument. else if (RuntimePropertyType.IsGenericType && RuntimePropertyType.FullName.StartsWith(DefaultImmutableConverter.ImmutableNamespace) && RuntimePropertyType.GetGenericArguments().Length == 1) { DefaultImmutableConverter.RegisterImmutableCollection(RuntimePropertyType, elementType, Options); EnumerableConverter = s_jsonImmutableConverter; } } } else { ShouldSerialize = HasGetter && !Options.IgnoreReadOnlyProperties; } } }