/// <summary> /// 构造类型转换器。 /// </summary> /// <param name="conversion">使用的类型转换。</param> /// <param name="inputType">要转换的对象的类型。</param> /// <param name="outputType">要将输入对象转换到的类型。</param> /// <param name="isChecked">是否执行溢出检查。</param> /// <param name="buildGeneric"><c>true</c> 表示需要生成泛型类型转换委托;<c>false</c> /// 表示需要生成非泛型的类型转换委托。</param> /// <returns>将对象从 <paramref name="inputType"/> 类型转换为 <paramref name="outputType"/> 类型的转换器。</returns> private static Delegate BuildConverter(Conversion conversion, Type inputType, Type outputType, bool isChecked, bool buildGeneric) { Contract.Requires(conversion != null && inputType != null && outputType != null); Contract.Ensures(Contract.Result <Delegate>() != null); var method = new DynamicMethod("Converter", buildGeneric ? outputType : typeof(object), new[] { buildGeneric?inputType: typeof(object) }, true); var il = method.GetILGenerator(); var passByAddress = conversion is FromNullableConversion; if (passByAddress && (buildGeneric || !inputType.IsValueType)) { il.Emit(OpCodes.Ldarga_S, (byte)0); } else { il.Emit(OpCodes.Ldarg_0); } if (buildGeneric) { conversion.Emit(il, inputType, outputType, isChecked); il.Emit(OpCodes.Ret); return(method.CreateDelegate(typeof(Converter <,>).MakeGenericType(inputType, outputType))); } // 从 object 拆箱得到值类型。 ConversionFactory.GetPreDefinedConversionNotVoid(typeof(object), inputType).Emit(il, typeof(object), inputType, isChecked); if (passByAddress) { il.EmitGetAddress(inputType); } conversion.Emit(il, inputType, outputType, isChecked); // 值类型装箱为 object。 if (outputType.IsValueType) { il.Emit(OpCodes.Box, outputType); } il.Emit(OpCodes.Ret); return(method.CreateDelegate(typeof(Converter <object, object>))); }