コード例 #1
0
        /// <summary>
        /// Converts the specified value, using the specified default value and format
        /// </summary>
        /// <param name="value">The value to convert</param>
        /// <param name="defaultValue">The default value (used for null, or DBNull.Value)</param>
        /// <param name="format">The format</param>
        /// <param name="conversionObserver">The conversion observer</param>
        /// <returns>The converted value</returns>
        public object Convert(object value, object defaultValue, IFormatProvider format, IConversionObserver conversionObserver)
        {
            if ((value == null) || ConversionsHelper.IsDBNull(value))
            {
                // value is null or DBNull
                return(defaultValue);
            }

            var sourceValueType = value.GetType();

            if (sourceValueType == null)
            {
                // unable to get the source value type
                return(defaultValue);
            }

            var sourceValueTypeInfo = sourceValueType.GetTypeInfo();

            if (sourceValueTypeInfo == null)
            {
                // unable to get the source value type
                return(defaultValue);
            }

            if ((sourceValueType != this.fromType) && (!this.fromTypeInfo.IsAssignableFrom(sourceValueTypeInfo)))
            {
                // the value cannot be converted to source type
                return(defaultValue);
            }

            var targetDefaultValueType = this.toType;

            if (defaultValue == null)
            {
                if (this.toTypeInfo.IsValueType)
                {
                    defaultValue = default(TTo);
                }
            }
            else
            {
                targetDefaultValueType = defaultValue.GetType();
                if (targetDefaultValueType == null)
                {
                    targetDefaultValueType = this.toType;
                    defaultValue           = default(TTo);
                }
            }

            var defaultTargetValueTypeInfo = targetDefaultValueType.GetTypeInfo();

            if ((targetDefaultValueType != this.toType) && (!this.toTypeInfo.IsAssignableFrom(defaultTargetValueTypeInfo)))
            {
                targetDefaultValueType = this.toType;
                defaultValue           = default(TTo);
            }

            return(this.ConvertValue((TFrom)value, (TTo)defaultValue, format, conversionObserver));
        }
コード例 #2
0
        /// <summary>
        /// Converts the value to the target type using the provided default value and format
        /// </summary>
        /// <param name="value">The value to convert</param>
        /// <param name="defaultValue">The default value to use for null or DBNull.Value</param>
        /// <param name="format">The format</param>
        /// <param name="conversionObserver">The conversion observer</param>
        /// <returns>The conversion result</returns>
        protected override object ConvertValue(object value, object defaultValue, IFormatProvider format, IConversionObserver conversionObserver)
        {
            object converted = defaultValue;

            bool targetIsEnum = this.toTypeInfo.IsEnum;

            if (targetIsEnum && Enum.IsDefined(this.toType, value))
            {
                // handle Enums
                string stringEnumValue = value.ToString();
                if (!string.IsNullOrWhiteSpace(stringEnumValue))
                {
                    converted = Enum.Parse(this.toType, stringEnumValue);
                    return(converted);
                }
            }
            else
            {
                // check for implicit operators
                object implicitOpResult;
                var    hasImplicitConversion = ConversionsHelper.HasImplicitConversionOperator(value, this.ToType, out implicitOpResult);
                if (hasImplicitConversion)
                {
                    converted = implicitOpResult;
                    return(converted);
                }

                // check for explicit operators
                object explicitOpResult;
                var    hasExplicitConversion = ConversionsHelper.HasExplicitConversionOperator(value, this.ToType, out explicitOpResult);
                if (hasExplicitConversion)
                {
                    converted = explicitOpResult;
                    return(converted);
                }

                converted = System.Convert.ChangeType(value, this.toType, format);
            }

            return(converted);
        }
コード例 #3
0
        /// <summary>
        /// Converts a value to the specified type
        /// </summary>
        /// <param name="value">The value to convert</param>
        /// <param name="targetType">The type to which the value should be converted</param>
        /// <param name="targetDefaultValue">The default value to use instead of null or DBNull.Value</param>
        /// <param name="format">The format used for conversion</param>
        /// <param name="conversionObserver">Conversion observer</param>
        /// <returns>The converted value</returns>
        public static object Convert(object value, Type targetType, object targetDefaultValue, IFormatProvider format, IConversionObserver conversionObserver)
        {
            if (targetType == null)
            {
                throw new ArgumentNullException("targetType");
            }

            TypeInfo targetTypeInfo = targetType.GetTypeInfo();

            if (targetTypeInfo == null)
            {
                throw new ArgumentException(string.Format("Unable to get type information for type {0}", targetType));
            }

            if (targetTypeInfo.IsValueType && ((targetDefaultValue == null) || (ConversionsHelper.IsDBNull(targetDefaultValue))))
            {
                // converting to a value type, but having the default value as null / DBNull
                targetDefaultValue = ConversionsHelper.GetDefaultValue(targetType);
            }

            if ((value == null) || ConversionsHelper.IsDBNull(value) || ConversionsHelper.IsStringEmptyOrWhitespace(value))
            {
                // converting null / DBNull / empty or whitespaces-only string to target type => just return default value
                if (conversionObserver != null)
                {
                    conversionObserver.NotifyKnownFallbackToDefaultValue(
                        value: value,
                        targetType: targetType,
                        defaultTargetValue: targetDefaultValue,
                        format: format,
                        fallbackReason: new ArgumentNullException("value"));
                }

                return(targetDefaultValue);
            }

            object converted = targetDefaultValue;

            try
            {
                // Handle Nullable<T>: try to convert to underlying T
                bool targetIsGenericType = ConversionsHelper.IsGenericType(targetTypeInfo);
                if (targetIsGenericType)
                {
                    Type nullableTypeArg;
                    if (ConversionsHelper.TryParseNullableType(targetType, out nullableTypeArg))
                    {
                        targetType = nullableTypeArg;
                    }
                }

                var bootstrapper = Converter.Settings.SpecializedConversionsBootstrapper;
                if (bootstrapper == null)
                {
                    bootstrapper = new DefaultSpecializedConversionsBootstrapper();
                }

                var converter = SpecializedConverterLocator.GetSpecializedConverter(value.GetType(), targetType, bootstrapper.DiscoveredSpecializedConverters);
                if (converter == null)
                {
                    converter = new GenericConverter(targetType);
                }

                converted = converter.Convert(value, targetDefaultValue, format, conversionObserver);
            }
            catch (Exception ex)
            {
                if (
                    // Convert.ChangeType may throw InvalidCastException when:
                    //   - This conversion is not supported OR
                    //   - value is null and conversionType is a value type OR
                    //   - value does not implement the IConvertible interface
                    (ex is InvalidCastException) ||

                    // Convert.ChangeType may throw FormatException when :
                    //   - value is not in a format for conversionType recognized by provider.
                    (ex is FormatException) ||

                    // Convert.ChangeType may throw OverflowException when:
                    //   - value represents a number that is out of the range of conversionType.
                    // - or -
                    // Enum.Parse may throw OverflowException when:
                    //   - value is outside the range of the underlying type of enumType
                    (ex is OverflowException) ||

                    // Convert.ChangeType may throw ArgumentNullException when :
                    //   - conversionType is null.
                    // - or -
                    // Enum.IsDefined may throw System.ArgumentNullException when:
                    //   - enumType or value is null
                    // - or -
                    // Enum.Parse may throw ArgumentNullException when :
                    //   - enumType or value is null.
                    (ex is ArgumentNullException) ||

                    // Enum.IsDefined may throw System.ArgumentException when:
                    //   - enumType is not an Enum.
                    //   - The type of value is an enumeration, but it is not an enumeration of type enumType.
                    //   - The type of value is not an underlying type of enumType.
                    // - or -
                    // Enum.Parse may throw ArgumentException when:
                    //   - enumType is not an Enum
                    //   - value is either an empty string or only contains white space
                    //   - value is a name, but not one of the named constants defined for the enumeration
                    (ex is ArgumentException) ||

                    // Enum.IsDefined may throwSystem.InvalidOperationException when:
                    //   - value is not type System.SByte, System.Int16, System.Int32, System.Int64, System.Byte, System.UInt16, System.UInt32, or System.UInt64, or System.String.
                    (ex is InvalidOperationException))
                {
                    if (conversionObserver != null)
                    {
                        conversionObserver.NotifyCaughtConversionException(
                            value: value,
                            targetType: targetType,
                            defaultTargetValue: targetDefaultValue,
                            format: format,
                            conversionException: ex);
                    }
                }
                else
                {
                    throw;
                }
            }

            return(converted);
        }