/// <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); }
/// <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; })); }
/// <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)); }
/// <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>); }
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); } }
/// <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))); }
/// <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); }
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); } }
/// <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))); }
/// <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)); }