示例#1
0
        private static ConvertResult TryConvertInternal(object initialValue, CultureInfo culture, Type targetType, out object value)
        {
            if (initialValue == null)
            {
                throw new ArgumentNullException("initialValue");
            }

            if (ReflectionUtils.IsNullableType(targetType))
            {
                targetType = Nullable.GetUnderlyingType(targetType);
            }

            Type initialType = initialValue.GetType();

            if (targetType == initialType)
            {
                value = initialValue;
                return(ConvertResult.Success);
            }

            // use Convert.ChangeType if both types are IConvertible
            if (ConvertUtils.IsConvertible(initialValue.GetType()) && ConvertUtils.IsConvertible(targetType))
            {
                if (targetType.IsEnum())
                {
                    if (initialValue is string)
                    {
                        value = Enum.Parse(targetType, initialValue.ToString(), true);
                        return(ConvertResult.Success);
                    }
                    else if (IsInteger(initialValue))
                    {
                        value = Enum.ToObject(targetType, initialValue);
                        return(ConvertResult.Success);
                    }
                }

                value = System.Convert.ChangeType(initialValue, targetType, culture);
                return(ConvertResult.Success);
            }

#if !NET20
            if (initialValue is DateTime && targetType == typeof(DateTimeOffset))
            {
                value = new DateTimeOffset((DateTime)initialValue);
                return(ConvertResult.Success);
            }
#endif

            if (initialValue is byte[] && targetType == typeof(Guid))
            {
                value = new Guid((byte[])initialValue);
                return(ConvertResult.Success);
            }

            if (initialValue is Guid && targetType == typeof(byte[]))
            {
                value = ((Guid)initialValue).ToByteArray();
                return(ConvertResult.Success);
            }

            if (initialValue is string)
            {
                if (targetType == typeof(Guid))
                {
                    value = new Guid((string)initialValue);
                    return(ConvertResult.Success);
                }
                if (targetType == typeof(Uri))
                {
                    value = new Uri((string)initialValue, UriKind.RelativeOrAbsolute);
                    return(ConvertResult.Success);
                }
                if (targetType == typeof(TimeSpan))
                {
                    value = ParseTimeSpan((string)initialValue);
                    return(ConvertResult.Success);
                }
                if (targetType == typeof(byte[]))
                {
                    value = System.Convert.FromBase64String((string)initialValue);
                    return(ConvertResult.Success);
                }
                if (typeof(Type).IsAssignableFrom(targetType))
                {
                    value = Type.GetType((string)initialValue, true);
                    return(ConvertResult.Success);
                }
            }

#if !(NET20 || NET35 || PORTABLE40 || PORTABLE)
            if (targetType == typeof(BigInteger))
            {
                value = ToBigInteger(initialValue);
                return(ConvertResult.Success);
            }
            if (initialValue is BigInteger)
            {
                value = FromBigInteger((BigInteger)initialValue, targetType);
                return(ConvertResult.Success);
            }
#endif

#if !(NETFX_CORE || PORTABLE40 || PORTABLE)
            // see if source or target types have a TypeConverter that converts between the two
            TypeConverter toConverter = GetConverter(initialType);

            if (toConverter != null && toConverter.CanConvertTo(targetType))
            {
                value = toConverter.ConvertTo(null, culture, initialValue, targetType);
                return(ConvertResult.Success);
            }

            TypeConverter fromConverter = GetConverter(targetType);

            if (fromConverter != null && fromConverter.CanConvertFrom(initialType))
            {
                value = fromConverter.ConvertFrom(null, culture, initialValue);
                return(ConvertResult.Success);
            }
#endif
#if !(NETFX_CORE || PORTABLE40 || PORTABLE)
            // handle DBNull and INullable
            if (initialValue == DBNull.Value)
            {
                if (ReflectionUtils.IsNullable(targetType))
                {
                    value = EnsureTypeAssignable(null, initialType, targetType);
                    return(ConvertResult.Success);
                }

                // cannot convert null to non-nullable
                value = null;
                return(ConvertResult.CannotConvertNull);
            }
#endif
#if !(NETFX_CORE || PORTABLE40 || PORTABLE)
            if (initialValue is INullable)
            {
                value = EnsureTypeAssignable(ToValue((INullable)initialValue), initialType, targetType);
                return(ConvertResult.Success);
            }
#endif

            if (targetType.IsInterface() || targetType.IsGenericTypeDefinition() || targetType.IsAbstract())
            {
                value = null;
                return(ConvertResult.NotInstantiableType);
            }

            value = null;
            return(ConvertResult.NoValidConversion);
        }