Esempio n. 1
0
        public static bool TryConvert <T>(object value, out T result)
        {
            // Check for null
            if (value == null)
            {
                result = default(T);
                return(!typeof(T).IsValueType);
            }

            // Just return if they're the same type
            if (typeof(T) == value.GetType())
            {
                result = (T)value;
                return(true);
            }

            // Check a normal conversion (in case it's a special type that implements a cast, IConvertible, or something)
            if (MetadataTypeConverter <T> .TryConvert(value, out result))
            {
                return(true);
            }

            // Check for enumerable conversions (but don't treat string as an enumerable)
            IEnumerable enumerable = value is string?null : value as IEnumerable;

            enumerable = enumerable ?? new[] { value };

            // IList<>
            if (typeof(T).IsConstructedGenericType && typeof(T).GetGenericTypeDefinition() == typeof(IList <>))
            {
                Type elementType = typeof(T).GetGenericArguments()[0];
                Type adapterType = typeof(MetadataTypeConverter <>).MakeGenericType(elementType);
                MetadataTypeConverter converter = (MetadataTypeConverter)Activator.CreateInstance(adapterType);
                result = (T)converter.ToList(enumerable);
                return(true);
            }

            // Array
            if (typeof(T).IsArray && typeof(T).GetArrayRank() == 1)
            {
                Type elementType = typeof(T).GetElementType();
                Type adapterType = typeof(MetadataTypeConverter <>).MakeGenericType(elementType);
                MetadataTypeConverter converter = (MetadataTypeConverter)Activator.CreateInstance(adapterType);
                result = (T)converter.ToArray(enumerable);
                return(true);
            }

            // IEnumerable<>
            if (typeof(T).IsConstructedGenericType && typeof(T).GetGenericTypeDefinition() == typeof(IEnumerable <>))
            {
                Type elementType = typeof(T).GetGenericArguments()[0];
                Type adapterType = typeof(MetadataTypeConverter <>).MakeGenericType(elementType);
                MetadataTypeConverter converter = (MetadataTypeConverter)Activator.CreateInstance(adapterType);
                result = (T)converter.ToEnumerable(enumerable);
                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        public static bool TryConvert <T>(object value, out T result)
        {
            // Check for null
            if (value == null)
            {
                result = default(T);
                return(!typeof(T).IsValueType);
            }

            // Just return if they're the same type
            if (typeof(T) == value.GetType())
            {
                result = (T)value;
                return(true);
            }

            // Check a normal conversion (in case it's a special type that implements a cast, IConvertible, or something)
            if (MetadataTypeConverter <T> .TryConvert(value, out result))
            {
                return(true);
            }

            // IReadOnlyList<>
            if (typeof(T).IsConstructedGenericType && typeof(T).GetGenericTypeDefinition() == typeof(IReadOnlyList <>))
            {
                return(TryConvertEnumerable(value, x => x.GetGenericArguments()[0], (x, y) => x.ToReadOnlyList(y), out result));
            }

            // IList<>
            if (typeof(T).IsConstructedGenericType &&
                (typeof(T).GetGenericTypeDefinition() == typeof(IList <>) ||
                 typeof(T).GetGenericTypeDefinition() == typeof(List <>)))
            {
                return(TryConvertEnumerable(value, x => x.GetGenericArguments()[0], (x, y) => x.ToList(y), out result));
            }

            // Array
            if (typeof(Array).IsAssignableFrom(typeof(T)) ||
                (typeof(T).IsArray && typeof(T).GetArrayRank() == 1))
            {
                return(TryConvertEnumerable(value, x => x.GetElementType() ?? typeof(object), (x, y) => x.ToArray(y), out result));
            }

            // IEnumerable<>
            if (typeof(T).IsConstructedGenericType && typeof(T).GetGenericTypeDefinition() == typeof(IEnumerable <>))
            {
                return(TryConvertEnumerable(value, x => x.GetGenericArguments()[0], (x, y) => x.ToEnumerable(y), out result));
            }

            return(false);
        }
Esempio n. 3
0
        private static bool TryConvertEnumerable <T>(object value, Func <Type, Type> elementTypeFunc,
                                                     Func <MetadataTypeConverter, IEnumerable, object> conversionFunc, out T result)
        {
            Type        elementType = elementTypeFunc(typeof(T));
            IEnumerable enumerable  = value is string?null : value as IEnumerable;

            if (enumerable == null || elementType.IsInstanceOfType(value))
            {
                enumerable = new[] { value };
            }
            Type adapterType = typeof(MetadataTypeConverter <>).MakeGenericType(elementType);
            MetadataTypeConverter converter = (MetadataTypeConverter)Activator.CreateInstance(adapterType);

            result = (T)conversionFunc(converter, enumerable);
            return(true);
        }