private static void ValidateNullability(object obj, ContextualType type, HashSet <object>?checkedObjects, List <string>?errors, bool stopFirstFail)
        {
            if (DisableNullabilityValidation)
            {
                return;
            }

            if (stopFirstFail && errors is not null && errors.Any())
            {
                return;
            }

            if (checkedObjects != null)
            {
                if (checkedObjects.Contains(obj))
                {
                    return;
                }
                else
                {
                    checkedObjects.Add(obj);
                }
            }

            if (checkedObjects != null && obj is IDictionary dictionary)
            {
                foreach (var item in dictionary.Keys.Cast <object>()
                         .Concat(dictionary.Values.Cast <object>()))
                {
                    ValidateNullability(item, type.GenericArguments[1], checkedObjects, errors, stopFirstFail);
                }
            }
            else if (checkedObjects != null && obj is IEnumerable enumerable && !(obj is string))
            {
                var itemType = type.ElementType ?? type.GenericArguments[0];
                foreach (var item in enumerable.Cast <object>())
                {
                    if (item == null)
                    {
                        if (itemType.Nullability == Nullability.NotNullable)
                        {
                            throw new InvalidOperationException(
                                      "The object's nullability is invalid, item in enumerable.");
                        }
                    }
                    else
                    {
                        ValidateNullability(item, itemType, checkedObjects, errors, stopFirstFail);
                    }
                }
            }
Exemplo n.º 2
0
        /// <summary>
        /// Gets a <see cref="CachedType"/> for the given <see cref="Type"/> instance.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The <see cref="CachedType"/>.</returns>
        public static ContextualType ToContextualType(this Type type)
        {
            var key = "Type:Context:" + type.FullName;

            lock (Lock)
            {
                if (!Cache.ContainsKey(key))
                {
                    Cache[key] = ContextualType.ForType(type, new Attribute[0]);
                }

                return((ContextualType)Cache[key]);
            }
        }
Exemplo n.º 3
0
        internal ContextualType(Type type, IEnumerable <Attribute> contextAttributes, ContextualType parent, byte[] nullableFlags, ref int nullableFlagsIndex, IEnumerable <dynamic> customAttributeProviders)
            : base(type)
        {
            Parent            = parent;
            ContextAttributes = contextAttributes is Attribute[]?
                                (Attribute[])contextAttributes :
                                contextAttributes?.ToArray() ??
                                new Attribute[0];

            _nullableFlags = nullableFlags;
            InitializeNullableFlagsAndOriginalNullability(ref nullableFlagsIndex, customAttributeProviders);

            if (_nullableFlags != null)
            {
                UpdateOriginalGenericArguments(ref nullableFlagsIndex);
            }
        }
Exemplo n.º 4
0
 /// <summary>
 /// Gets an uncached <see cref="ContextualType"/> for the given <see cref="Type"/> instance and attributes.
 /// </summary>
 /// <param name="type">The type.</param>
 /// <param name="attributes">The attributes.</param>
 /// <returns>The <see cref="CachedType"/>.</returns>
 public static ContextualType ToContextualType(this Type type, IEnumerable <Attribute> attributes)
 {
     // TODO: Is there a way to cache these contextual types?
     return(ContextualType.ForType(type, attributes));
 }