private static bool GetCachedCanConvertToBoolean(Type type)
        {
            if (BoolConvertCache.TryGetValue(type, out bool result))
            {
                return(result);
            }

            if (CustomBooleanTypeConverter.CanConvertFrom(type))
            {
                return(BoolConvertCache[type] = true);
            }

            return(BoolConvertCache[type] = false);
        }
Example #2
0
        /// <summary>
        /// Tries to convert the input object to the output type using TypeConverters. If the destination type is a superclass of the input type,
        /// if will use <see cref="Convert.ChangeType(object,System.Type)"/>.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="destinationType">Type of the destination.</param>
        /// <returns></returns>
        public static Attempt <object> TryConvertTo(this object input, Type destinationType)
        {
            if (input == null)
            {
                return(Attempt <object> .False);
            }

            if (destinationType == typeof(object))
            {
                return(new Attempt <object>(true, input));
            }

            if (input.GetType() == destinationType)
            {
                return(new Attempt <object>(true, input));
            }

            if (!destinationType.IsGenericType || destinationType.GetGenericTypeDefinition() != typeof(Nullable <>))
            {
                if (TypeHelper.IsTypeAssignableFrom(destinationType, input.GetType()) &&
                    TypeHelper.IsTypeAssignableFrom <IConvertible>(input))
                {
                    var casted = Convert.ChangeType(input, destinationType);
                    return(new Attempt <object>(true, casted));
                }
            }

            var inputConverter = TypeDescriptor.GetConverter(input);

            if (inputConverter.CanConvertTo(destinationType))
            {
                try
                {
                    var converted = inputConverter.ConvertTo(input, destinationType);
                    return(new Attempt <object>(true, converted));
                }
                catch (Exception e)
                {
                    return(new Attempt <object>(e));
                }
            }

            if (destinationType == typeof(bool))
            {
                var boolConverter = new CustomBooleanTypeConverter();
                if (boolConverter.CanConvertFrom(input.GetType()))
                {
                    try
                    {
                        var converted = boolConverter.ConvertFrom(input);
                        return(new Attempt <object>(true, converted));
                    }
                    catch (Exception e)
                    {
                        return(new Attempt <object>(e));
                    }
                }
            }

            var outputConverter = TypeDescriptor.GetConverter(destinationType);

            if (outputConverter.CanConvertFrom(input.GetType()))
            {
                try
                {
                    var converted = outputConverter.ConvertFrom(input);
                    return(new Attempt <object>(true, converted));
                }
                catch (Exception e)
                {
                    return(new Attempt <object>(e));
                }
            }


            if (TypeHelper.IsTypeAssignableFrom <IConvertible>(input))
            {
                try
                {
                    var casted = Convert.ChangeType(input, destinationType);
                    return(new Attempt <object>(true, casted));
                }
                catch (Exception e)
                {
                    return(new Attempt <object>(e));
                }
            }

            return(Attempt <object> .False);
        }
Example #3
0
        /// <summary>
        /// Tries to convert the input object to the output type using TypeConverters. If the destination type is a superclass of the input type,
        /// if will use <see cref="Convert.ChangeType(object,System.Type)"/>.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="destinationType">Type of the destination.</param>
        /// <returns></returns>
        public static Attempt <object> TryConvertTo(this object input, Type destinationType)
        {
            if (input == null)
            {
                return(Attempt <object> .Fail());
            }

            if (destinationType == typeof(object))
            {
                return(Attempt.Succeed(input));
            }

            if (input.GetType() == destinationType)
            {
                return(Attempt.Succeed(input));
            }

            //check for string so that overloaders of ToString() can take advantage of the conversion.
            if (destinationType == typeof(string))
            {
                return(Attempt <object> .Succeed(input.ToString()));
            }

            // if we've got a nullable of something, we try to convert directly to that thing.
            if (destinationType.IsGenericType && destinationType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                var underlyingType = Nullable.GetUnderlyingType(destinationType);

                //special case for empty strings for bools/dates which should return null if an empty string
                var asString = input as string;
                if (asString != null && string.IsNullOrEmpty(asString) && (underlyingType == typeof(DateTime) || underlyingType == typeof(bool)))
                {
                    return(Attempt <object> .Succeed(null));
                }

                // recursively call into myself with the inner (not-nullable) type and handle the outcome
                var nonNullable = input.TryConvertTo(underlyingType);

                // and if sucessful, fall on through to rewrap in a nullable; if failed, pass on the exception
                if (nonNullable.Success)
                {
                    input = nonNullable.Result;                     // now fall on through...
                }
                else
                {
                    return(Attempt <object> .Fail(nonNullable.Exception));
                }
            }

            // we've already dealed with nullables, so any other generic types need to fall through
            if (!destinationType.IsGenericType)
            {
                if (input is string)
                {
                    var result = TryConvertToFromString(input as string, destinationType);

                    // if we processed the string (succeed or fail), we're done
                    if (result.HasValue)
                    {
                        return(result.Value);
                    }
                }

                //TODO: Do a check for destination type being IEnumerable<T> and source type implementing IEnumerable<T> with
                // the same 'T', then we'd have to find the extension method for the type AsEnumerable() and execute it.

                if (TypeHelper.IsTypeAssignableFrom(destinationType, input.GetType()) &&
                    TypeHelper.IsTypeAssignableFrom <IConvertible>(input))
                {
                    try
                    {
                        var casted = Convert.ChangeType(input, destinationType);
                        return(Attempt.Succeed(casted));
                    }
                    catch (Exception e)
                    {
                        return(Attempt <object> .Fail(e));
                    }
                }
            }

            var inputConverter = TypeDescriptor.GetConverter(input);

            if (inputConverter.CanConvertTo(destinationType))
            {
                try
                {
                    var converted = inputConverter.ConvertTo(input, destinationType);
                    return(Attempt.Succeed(converted));
                }
                catch (Exception e)
                {
                    return(Attempt <object> .Fail(e));
                }
            }

            if (destinationType == typeof(bool))
            {
                var boolConverter = new CustomBooleanTypeConverter();
                if (boolConverter.CanConvertFrom(input.GetType()))
                {
                    try
                    {
                        var converted = boolConverter.ConvertFrom(input);
                        return(Attempt.Succeed(converted));
                    }
                    catch (Exception e)
                    {
                        return(Attempt <object> .Fail(e));
                    }
                }
            }

            var outputConverter = TypeDescriptor.GetConverter(destinationType);

            if (outputConverter.CanConvertFrom(input.GetType()))
            {
                try
                {
                    var converted = outputConverter.ConvertFrom(input);
                    return(Attempt.Succeed(converted));
                }
                catch (Exception e)
                {
                    return(Attempt <object> .Fail(e));
                }
            }

            if (TypeHelper.IsTypeAssignableFrom <IConvertible>(input))
            {
                try
                {
                    var casted = Convert.ChangeType(input, destinationType);
                    return(Attempt.Succeed(casted));
                }
                catch (Exception e)
                {
                    return(Attempt <object> .Fail(e));
                }
            }

            return(Attempt <object> .Fail());
        }
Example #4
0
        /// <summary>
        /// Tries to convert the input object to the output type using TypeConverters. If the destination type is a superclass of the input type,
        /// if will use <see cref="Convert.ChangeType(object,System.Type)"/>.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="destinationType">Type of the destination.</param>
        /// <returns></returns>
        public static Attempt <object> TryConvertTo(this object input, Type destinationType)
        {
            if (input == null)
            {
                return(Attempt <object> .False);
            }

            if (destinationType == typeof(object))
            {
                return(new Attempt <object>(true, input));
            }

            if (input.GetType() == destinationType)
            {
                return(new Attempt <object>(true, input));
            }

            if (!destinationType.IsGenericType || destinationType.GetGenericTypeDefinition() != typeof(Nullable <>))
            {
                //TODO: Do a check for destination type being IEnumerable<T> and source type implementing IEnumerable<T> with
                // the same 'T', then we'd have to find the extension method for the type AsEnumerable() and execute it.

                if (TypeHelper.IsTypeAssignableFrom(destinationType, input.GetType()) &&
                    TypeHelper.IsTypeAssignableFrom <IConvertible>(input))
                {
                    try
                    {
                        var casted = Convert.ChangeType(input, destinationType);
                        return(new Attempt <object>(true, casted));
                    }
                    catch (Exception e)
                    {
                        return(new Attempt <object>(e));
                    }
                }
            }

            var inputConverter = TypeDescriptor.GetConverter(input);

            if (inputConverter.CanConvertTo(destinationType))
            {
                try
                {
                    var converted = inputConverter.ConvertTo(input, destinationType);
                    return(new Attempt <object>(true, converted));
                }
                catch (Exception e)
                {
                    return(new Attempt <object>(e));
                }
            }

            if (destinationType == typeof(bool))
            {
                var boolConverter = new CustomBooleanTypeConverter();
                if (boolConverter.CanConvertFrom(input.GetType()))
                {
                    try
                    {
                        var converted = boolConverter.ConvertFrom(input);
                        return(new Attempt <object>(true, converted));
                    }
                    catch (Exception e)
                    {
                        return(new Attempt <object>(e));
                    }
                }
            }

            var outputConverter = TypeDescriptor.GetConverter(destinationType);

            if (outputConverter.CanConvertFrom(input.GetType()))
            {
                try
                {
                    var converted = outputConverter.ConvertFrom(input);
                    return(new Attempt <object>(true, converted));
                }
                catch (Exception e)
                {
                    return(new Attempt <object>(e));
                }
            }


            if (TypeHelper.IsTypeAssignableFrom <IConvertible>(input))
            {
                try
                {
                    var casted = Convert.ChangeType(input, destinationType);
                    return(new Attempt <object>(true, casted));
                }
                catch (Exception e)
                {
                    return(new Attempt <object>(e));
                }
            }

            return(Attempt <object> .False);
        }