internal JsonContract(Type underlyingType) { ValidationUtils.ArgumentNotNull(underlyingType, nameof(underlyingType)); UnderlyingType = underlyingType; // resolve ByRef types // typically comes from in and ref parameters on methods/ctors underlyingType = ReflectionUtils.EnsureNotByRefType(underlyingType); IsNullable = ReflectionUtils.IsNullable(underlyingType); NonNullableUnderlyingType = IsNullable && ReflectionUtils.IsNullableType(underlyingType) ? Nullable.GetUnderlyingType(underlyingType) : underlyingType; _createdType = CreatedType = NonNullableUnderlyingType; IsConvertable = ConvertUtils.IsConvertible(NonNullableUnderlyingType); IsEnum = NonNullableUnderlyingType.IsEnum(); InternalReadType = ReadType.Read; }
public ObjectContract(Type underlyingType) : base(underlyingType) { ContractType = ContractType.Object; DefaultConstructor = NonNullableUnderlyingType.GetConstructors(BindingFlags.Instance | BindingFlags.Public) .FirstOrDefault(c => c.GetParameters().Length == 0); Parameters = new ParameterInfo[] {}; if (DefaultConstructor == null) { ParameterizedConstructor = NonNullableUnderlyingType.GetConstructors(BindingFlags.Instance | BindingFlags.Public) .OrderBy(c => c.GetParameters().Length) .FirstOrDefault(); Parameters = ParameterizedConstructor?.GetParameters() ?? new ParameterInfo[] {}; if (ParameterizedConstructor == null) { throw new Exceptions.NapBindingException($"Could not locate a constructor on type {NonNullableUnderlyingType.FullName}"); } } }
public JsonDictionaryContract(Type underlyingType) : base(underlyingType) { ContractType = JsonContractType.Dictionary; Type?keyType; Type?valueType; if (ReflectionUtils.ImplementsGenericDefinition(NonNullableUnderlyingType, typeof(IDictionary <,>), out _genericCollectionDefinitionType)) { keyType = _genericCollectionDefinitionType.GetGenericArguments()[0]; valueType = _genericCollectionDefinitionType.GetGenericArguments()[1]; if (ReflectionUtils.IsGenericDefinition(NonNullableUnderlyingType, typeof(IDictionary <,>))) { CreatedType = typeof(Dictionary <,>).MakeGenericType(keyType, valueType); } else if (NonNullableUnderlyingType.IsGenericType()) { // ConcurrentDictionary<,> + IDictionary setter + null value = error // wrap to use generic setter // https://github.com/JamesNK/Newtonsoft.Json/issues/1582 var typeDefinition = NonNullableUnderlyingType.GetGenericTypeDefinition(); if (typeDefinition.FullName == JsonTypeReflector.ConcurrentDictionaryTypeName) { ShouldCreateWrapper = true; } } #if HAVE_READ_ONLY_COLLECTIONS IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(NonNullableUnderlyingType, typeof(ReadOnlyDictionary <,>)); #endif } #if HAVE_READ_ONLY_COLLECTIONS else if (ReflectionUtils.ImplementsGenericDefinition(NonNullableUnderlyingType, typeof(IReadOnlyDictionary <,>), out _genericCollectionDefinitionType)) { keyType = _genericCollectionDefinitionType.GetGenericArguments()[0]; valueType = _genericCollectionDefinitionType.GetGenericArguments()[1]; if (ReflectionUtils.IsGenericDefinition(NonNullableUnderlyingType, typeof(IReadOnlyDictionary <,>))) { CreatedType = typeof(ReadOnlyDictionary <,>).MakeGenericType(keyType, valueType); } IsReadOnlyOrFixedSize = true; } #endif else { ReflectionUtils.GetDictionaryKeyValueTypes(NonNullableUnderlyingType, out keyType, out valueType); if (NonNullableUnderlyingType == typeof(IDictionary)) { CreatedType = typeof(Dictionary <object, object>); } } if (keyType != null && valueType != null) { _parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor( CreatedType, typeof(KeyValuePair <,>).MakeGenericType(keyType, valueType), typeof(IDictionary <,>).MakeGenericType(keyType, valueType)); #if HAVE_FSHARP_TYPES if (!HasParameterizedCreatorInternal && NonNullableUnderlyingType.Name == FSharpUtils.FSharpMapTypeName) { FSharpUtils.EnsureInitialized(NonNullableUnderlyingType.Assembly()); _parameterizedCreator = FSharpUtils.Instance.CreateMap(keyType, valueType); } #endif } if (!typeof(IDictionary).IsAssignableFrom(CreatedType)) { ShouldCreateWrapper = true; } DictionaryKeyType = keyType; DictionaryValueType = valueType; #if (NET20 || NET35) if (DictionaryValueType != null && ReflectionUtils.IsNullableType(DictionaryValueType)) { // bug in .NET 2.0 & 3.5 that Dictionary<TKey, Nullable<TValue>> throws an error when adding null via IDictionary[key] = object // wrapper will handle calling Add(T) instead if (ReflectionUtils.InheritsGenericDefinition(CreatedType, typeof(Dictionary <,>), out _)) { ShouldCreateWrapper = true; } } #endif if (DictionaryKeyType != null && DictionaryValueType != null && ImmutableCollectionsUtils.TryBuildImmutableForDictionaryContract( NonNullableUnderlyingType, DictionaryKeyType, DictionaryValueType, out var immutableCreatedType, out var immutableParameterizedCreator)) { CreatedType = immutableCreatedType; _parameterizedCreator = immutableParameterizedCreator; IsReadOnlyOrFixedSize = true; } }