Example #1
0
        /// <summary>
        /// 将栈顶的对象从 <paramref name="inputType"/> 转换为 <paramref name="outputType"/>。
        /// </summary>
        /// <param name="il">IL 指令生成器。</param>
        /// <param name="inputType">要转换的对象的类型。</param>
        /// <param name="outputType">要将输入对象转换到的类型。</param>
        /// <param name="isChecked">是否执行溢出检查。</param>
        /// <exception cref="ArgumentNullException"><paramref name="il"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="inputType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="outputType"/> 为 <c>null</c>。</exception>
        public static void EmitConversion(this ILGenerator il, Type inputType, Type outputType, bool isChecked)
        {
            if (il == null)
            {
                throw CommonExceptions.ArgumentNull("il");
            }
            if (inputType == null)
            {
                throw CommonExceptions.ArgumentNull("inputType");
            }
            if (outputType == null)
            {
                throw CommonExceptions.ArgumentNull("outputType");
            }
            Contract.EndContractBlock();
            Conversion conversion = ConversionFactory.GetConversion(inputType, outputType);

            if (conversion == null)
            {
                throw CommonExceptions.InvalidCast(inputType, outputType);
            }
            if (conversion is FromNullableConversion)
            {
                il.EmitGetAddress(inputType);
            }
            conversion.Emit(il, inputType, outputType, isChecked);
        }
Example #2
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;
     }));
 }
Example #3
0
        /// <summary>
        /// 获取转换类型的指令生成器,能够将栈顶的对象从 <paramref name="inputType"/> 转换为
        /// <paramref name="outputType"/>。
        /// </summary>
        /// <param name="il">IL 指令生成器。</param>
        /// <param name="inputType">要转换的对象的类型。</param>
        /// <param name="outputType">要将输入对象转换到的类型。</param>
        /// <param name="conversionType">类型转换类型的限制。</param>
        /// <returns>类型转换的指令生成器,如果不能进行类型转换则返回 <c>null</c>。</returns>
        internal static Converter GetConversion(this ILGenerator il, Type inputType, Type outputType,
                                                ConversionType conversionType)
        {
            Contract.Requires(il != null && inputType != null && outputType != null);
            Contract.Requires(conversionType == ConversionType.Implicit ||
                              conversionType == ConversionType.Explicit ||
                              conversionType == ConversionType.UserDefined);
            Conversion conversion = conversionType == ConversionType.UserDefined ?
                                    ConversionFactory.GetConversion(inputType, outputType) :
                                    ConversionFactory.GetPreDefinedConversion(inputType, outputType);

            if (conversion == null || conversion.ConversionType > conversionType)
            {
                return(null);
            }
            return(new Converter(conversion, il, inputType, outputType));
        }
Example #4
0
        /// <summary>
        /// 获取将对象从 <typeparamref name="TInput"/> 类型转换为 <typeparamref name="TOutput"/> 类型的转换器。
        /// </summary>
        /// <typeparam name="TInput">输入对象的类型。</typeparam>
        /// <typeparam name="TOutput">输出对象的类型。</typeparam>
        /// <returns>将对象从 <typeparamref name="TInput"/> 类型转换为 <typeparamref name="TOutput"/> 类型的转换器。
        /// 如果不存在则为 <c>null</c>。</returns>
        /// <overloads>
        /// <summary>
        /// 获取将对象从一种类型转换为另一种类型的转换器。
        /// </summary>
        /// </overloads>
        public static Converter <TInput, TOutput> GetConverter <TInput, TOutput>()
        {
            var inputType  = typeof(TInput);
            var outputType = typeof(TOutput);
            var converter  = GetConverterInternal(inputType, outputType, true);

            if (converter == null)
            {
                return(null);
            }
            if (converter.GenericConverter == null)
            {
                converter.GenericConverter = BuildConverter(ConversionFactory.GetConversion(inputType, outputType),
                                                            inputType, outputType, false, true);
            }
            return(converter.GenericConverter as Converter <TInput, TOutput>);
        }
Example #5
0
 public static bool CanChangeType(Type inputType, Type outputType)
 {
     if (inputType == null)
     {
         throw CommonExceptions.ArgumentNull("inputType");
     }
     if (outputType == null)
     {
         throw CommonExceptions.ArgumentNull("outputType");
     }
     Contract.EndContractBlock();
     try
     {
         return(ConversionFactory.GetConversion(inputType, outputType) != null);
     }
     catch
     {
         return(false);
     }
 }
Example #6
0
        /// <summary>
        /// 获取将对象从 <paramref name="inputType"/> 类型转换为 <paramref name="outputType"/> 类型的转换器。
        /// </summary>
        /// <param name="inputType">要转换的对象的类型。</param>
        /// <param name="outputType">要将输入对象转换到的类型。</param>
        /// <returns>将对象从 <paramref name="inputType"/> 类型转换为 <paramref name="outputType"/> 类型的转换器。
        /// 如果不存在则为 <c>null</c>。</returns>
        /// <remarks>尽可能使用泛型方法 <see cref="GetConverter{TInput,TOutput}"/>,这样可以避免额外的类型转换。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="inputType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="outputType"/> 为 <c>null</c>。</exception>
        public static Converter <object, object> GetConverter(Type inputType, Type outputType)
        {
            if (inputType == null)
            {
                throw CommonExceptions.ArgumentNull("inputType");
            }
            if (outputType == null)
            {
                throw CommonExceptions.ArgumentNull("outputType");
            }
            Contract.EndContractBlock();
            Converter converter = GetConverterInternal(inputType, outputType, false);

            if (converter == null)
            {
                return(null);
            }
            return(converter.ObjectConverter ?? (converter.ObjectConverter = (Converter <object, object>)BuildConverter(
                                                     ConversionFactory.GetConversion(inputType, outputType), inputType, outputType, false, false)));
        }
Example #7
0
        /// <summary>
        /// 将栈顶的对象从 <paramref name="inputType"/> 转换为 <paramref name="outputType"/>。
        /// </summary>
        /// <param name="il">IL 指令生成器。</param>
        /// <param name="inputType">要转换的对象的类型。</param>
        /// <param name="outputType">要将输入对象转换到的类型。</param>
        /// <param name="isChecked">是否执行溢出检查。</param>
        /// <param name="conversionType">类型转换类型的限制。</param>
        internal static void EmitConversion(this ILGenerator il, Type inputType, Type outputType, bool isChecked,
                                            ConversionType conversionType)
        {
            Contract.Requires(il != null && inputType != null && outputType != null);
            Contract.Requires(conversionType == ConversionType.Implicit ||
                              conversionType == ConversionType.Explicit ||
                              conversionType == ConversionType.UserDefined);
            Conversion conversion = conversionType == ConversionType.UserDefined ?
                                    ConversionFactory.GetConversion(inputType, outputType) :
                                    ConversionFactory.GetPreDefinedConversion(inputType, outputType);

            if (conversion == null || conversion.ConversionType > conversionType)
            {
                throw CommonExceptions.InvalidCast(inputType, outputType);
            }
            if (conversion is FromNullableConversion)
            {
                il.EmitGetAddress(inputType);
            }
            conversion.Emit(il, inputType, outputType, isChecked);
        }
Example #8
0
 public static bool CanChangeType(Type inputType, Type outputType)
 {
     CommonExceptions.CheckArgumentNull(inputType, nameof(inputType));
     CommonExceptions.CheckArgumentNull(outputType, nameof(outputType));
     Contract.EndContractBlock();
     if (inputType.ContainsGenericParameters)
     {
         throw CommonExceptions.TypeContainsGenericParameters(inputType);
     }
     if (outputType.ContainsGenericParameters)
     {
         throw CommonExceptions.TypeContainsGenericParameters(outputType);
     }
     try
     {
         return(ConversionFactory.GetConversion(inputType, outputType) != null);
     }
     catch
     {
         return(false);
     }
 }
Example #9
0
        /// <summary>
        /// 获取将对象从 <paramref name="inputType"/> 类型转换为 <paramref name="outputType"/> 类型的转换器。
        /// </summary>
        /// <param name="inputType">要转换的对象的类型。</param>
        /// <param name="outputType">要将输入对象转换到的类型。</param>
        /// <returns>将对象从 <paramref name="inputType"/> 类型转换为 <paramref name="outputType"/> 类型的转换器。
        /// 如果不存在则为 <c>null</c>。</returns>
        /// <remarks>尽可能使用泛型方法 <see cref="GetConverter{TInput,TOutput}"/>,这样可以避免额外的类型转换。</remarks>
        /// <exception cref="ArgumentNullException"><paramref name="inputType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="outputType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentException"><paramref name="inputType"/> 包含泛型参数。</exception>
        /// <exception cref="ArgumentException"><paramref name="outputType"/> 包含泛型参数。</exception>
        public static Converter <object, object> GetConverter(Type inputType, Type outputType)
        {
            CommonExceptions.CheckArgumentNull(inputType, nameof(inputType));
            CommonExceptions.CheckArgumentNull(outputType, nameof(outputType));
            Contract.EndContractBlock();
            if (inputType.ContainsGenericParameters)
            {
                throw CommonExceptions.TypeContainsGenericParameters(inputType);
            }
            if (outputType.ContainsGenericParameters)
            {
                throw CommonExceptions.TypeContainsGenericParameters(outputType);
            }
            var converter = GetConverterInternal(inputType, outputType, false);

            if (converter == null)
            {
                return(null);
            }
            return(converter.ObjectConverter ?? (converter.ObjectConverter = (Converter <object, object>)BuildConverter(
                                                     ConversionFactory.GetConversion(inputType, outputType), inputType, outputType, false, false)));
        }
Example #10
0
        /// <summary>
        /// 获取转换类型的指令生成器,能够将栈顶的对象从 <paramref name="inputType"/> 转换为
        /// <paramref name="outputType"/>。
        /// </summary>
        /// <param name="il">IL 指令生成器。</param>
        /// <param name="inputType">要转换的对象的类型。</param>
        /// <param name="outputType">要将输入对象转换到的类型。</param>
        /// <exception cref="ArgumentNullException"><paramref name="il"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="inputType"/> 为 <c>null</c>。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="outputType"/> 为 <c>null</c>。</exception>
        public static Converter GetConversion(this ILGenerator il, Type inputType, Type outputType)
        {
            if (il == null)
            {
                throw CommonExceptions.ArgumentNull("il");
            }
            if (inputType == null)
            {
                throw CommonExceptions.ArgumentNull("inputType");
            }
            if (outputType == null)
            {
                throw CommonExceptions.ArgumentNull("outputType");
            }
            Contract.EndContractBlock();
            Conversion conversion = ConversionFactory.GetConversion(inputType, outputType);

            if (conversion == null)
            {
                throw CommonExceptions.InvalidCast(inputType, outputType);
            }
            return(new Converter(conversion, il, inputType, outputType));
        }