示例#1
0
        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;
        }
示例#2
0
        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}");
                }
            }
        }
示例#3
0
        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;
            }
        }