예제 #1
0
 /// <summary>
 /// 获取将对象从 <paramref name="inputType"/> 类型转换为 <paramref name="outputType"/> 类型的转换器。
 /// </summary>
 /// <param name="inputType">要转换的对象的类型。</param>
 /// <param name="outputType">要将输入对象转换到的类型。</param>
 /// <param name="buildGeneric"><c>true</c> 表示需要生成泛型类型转换委托;<c>false</c>
 /// 表示需要生成非泛型的类型转换委托。</param>
 /// <returns>将对象从 <paramref name="inputType"/> 类型转换为 <paramref name="outputType"/> 类型的转换器。
 /// 如果不存在则为 <c>null</c>。</returns>
 private static Converter GetConverterInternal(Type inputType, Type outputType, bool buildGeneric)
 {
     Contract.Requires(inputType != null && outputType != null);
     return(converterCache.GetOrAdd(new Tuple <Type, Type>(inputType, outputType), types =>
     {
         var conversion = ConversionFactory.GetConversion(inputType, outputType);
         if (conversion == null)
         {
             return null;
         }
         var converter = new Converter();
         var dlgConversion = conversion as DelegateConversion;
         if (dlgConversion != null)
         {
             converter.GenericConverter = dlgConversion.Converter;
             if (buildGeneric)
             {
                 return converter;
             }
         }
         if (conversion.ConversionType == ConversionType.Identity ||
             conversion.ConversionType == ConversionType.ImplicitReference ||
             conversion.ConversionType == ConversionType.Box ||
             conversion.ConversionType == ConversionType.Unbox)
         {
             converter.ObjectConverter = defaultObjectConverter;
             if (!buildGeneric)
             {
                 return converter;
             }
         }
         if (conversion.ConversionType == ConversionType.ExplicitReference)
         {
             // 对于显式引用转换,只需要检查一下实际类型是否是 outputType 即可。
             converter.ObjectConverter = obj =>
             {
                 if (obj != null && !outputType.IsInstanceOfType(obj))
                 {
                     throw CommonExceptions.InvalidCast(obj.GetType(), outputType);
                 }
                 return obj;
             };
             if (!buildGeneric)
             {
                 return converter;
             }
         }
         var dlg = BuildConverter(conversion, inputType, outputType, false, buildGeneric);
         if (buildGeneric)
         {
             converter.GenericConverter = dlg;
         }
         else
         {
             converter.ObjectConverter = (Converter <object, object>)dlg;
         }
         return converter;
     }));
 }
예제 #2
0
        /// <summary>
        /// 返回指定类型的对象,其值等效于指定对象。
        /// </summary>
        /// <typeparam name="TInput">要转换的对象的类型。</typeparam>
        /// <typeparam name="TOutput">要将 <paramref name="value"/> 转换到的类型。</typeparam>
        /// <param name="value">要转换的对象。</param>
        /// <returns>一个对象,其类型为 <typeparamref name="TOutput"/>,
        /// 并且其值等效于 <paramref name="value"/>。</returns>
        /// <exception cref="InvalidCastException">不支持此转换。</exception>
        /// <overloads>
        /// <summary>
        /// 返回指定类型的对象,其值等效于指定对象。
        /// </summary>
        /// </overloads>
        public static TOutput ChangeType <TInput, TOutput>(TInput value)
        {
            var converter = GetConverter <TInput, TOutput>();

            if (converter == null)
            {
                throw CommonExceptions.InvalidCast(typeof(TInput), typeof(TOutput));
            }
            return(converter(value));
        }
예제 #3
0
        /// <summary>
        /// 使用默认的类型转换方法将当前数组转换为另一种类型的数组。
        /// </summary>
        /// <typeparam name="TInput">源数组元素的类型。</typeparam>
        /// <typeparam name="TOutput">目标数组元素的类型。</typeparam>
        /// <param name="array">要转换为目标类型的一维数组。</param>
        /// <returns>目标类型的数组,包含从源数组转换而来的元素。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="array"/> 为 <c>null</c>。</exception>
        /// <exception cref="InvalidCastException"><typeparamref name="TInput"/> 类型不能转换到
        /// <typeparamref name="TOutput"/> 类型。</exception>
        public static TOutput[] ConvertAll <TInput, TOutput>(this TInput[] array)
        {
            CommonExceptions.CheckArgumentNull(array, "array");
            Contract.EndContractBlock();
            Converter <TInput, TOutput> converter = Convert.GetConverter <TInput, TOutput>();

            if (converter == null)
            {
                throw CommonExceptions.InvalidCast(typeof(TInput), typeof(TOutput));
            }
            return(Array.ConvertAll(array, converter));
        }
예제 #4
0
        /// <summary>
        /// 返回指定类型的对象,其值等效于指定对象。
        /// </summary>
        /// <typeparam name="TOutput">要转换到的类型。</typeparam>
        /// <param name="value">要将 <paramref name="value"/> 转换的对象。</param>
        /// <returns>一个对象,其类型为 <typeparamref name="TOutput"/>,
        /// 并且其值等效于 <paramref name="value"/>。</returns>
        /// <remarks>尽可能使用泛型方法 <see cref="ChangeType{TInput,TOutput}"/>,这样可以避免额外的类型转换。</remarks>
        /// <exception cref="InvalidCastException"><paramref name="value"/> 为 <c>null</c>,
        /// 而且 <typeparamref name="TOutput"/> 是值类型。</exception>
        /// <exception cref="InvalidCastException">不支持此转换。</exception>
        public static TOutput ChangeType <TOutput>(object value)
        {
            if (value == null)
            {
                if (typeof(TOutput).IsValueType)
                {
                    throw CommonExceptions.CannotCastNullToValueType();
                }
                return(default(TOutput));
            }
            var converter = GetConverter(value.GetType(), typeof(TOutput));

            if (converter == null)
            {
                throw CommonExceptions.InvalidCast(value.GetType(), typeof(TOutput));
            }
            return((TOutput)converter(value));
        }
예제 #5
0
        /// <summary>
        /// 返回指定类型的对象,其值等效于指定对象。
        /// </summary>
        /// <param name="value">要转换的对象。</param>
        /// <param name="outputType">要将 <paramref name="value"/> 转换到的类型。</param>
        /// <returns>一个对象,其类型为 <paramref name="outputType"/>,
        /// 并且其值等效于 <paramref name="value"/>。</returns>
        /// <remarks>尽可能使用泛型方法 <see cref="ChangeType{TInput,TOutput}"/>,这样可以避免额外的类型转换。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="outputType"/> 为 <c>null</c>。</exception>
        /// <exception cref="InvalidCastException"><paramref name="value"/> 为 <c>null</c>,
        /// 而且 <paramref name="outputType"/> 是值类型。</exception>
        /// <exception cref="InvalidCastException">不支持此转换。</exception>
        public static object ChangeType(object value, Type outputType)
        {
            CommonExceptions.CheckArgumentNull(outputType, nameof(outputType));
            Contract.EndContractBlock();
            if (value == null)
            {
                if (outputType.IsValueType)
                {
                    throw CommonExceptions.CannotCastNullToValueType();
                }
                return(null);
            }
            var converter = GetConverter(value.GetType(), outputType);

            if (converter == null)
            {
                throw CommonExceptions.InvalidCast(value.GetType(), outputType);
            }
            return(converter(value));
        }