private static void ConvertFromBoolean(ILGenerator il, OpCode conversionOpCode) { il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ceq); if (conversionOpCode == OpCodes.Call) { il.Emit(OpCodes.Call, DecimalMetadata.GetConversionMethodToDecimal(TypeCode.Int32)); } else { il.Emit(conversionOpCode); } }
public static void EmitConversion(ILGenerator il, Type from, Type to) { if (from.IsClass == false && ReferenceEquals(to, typeof(object))) { il.Emit(OpCodes.Box, from); return; } var fromTypeCode = Type.GetTypeCode(from); var toTypeCode = Type.GetTypeCode(to); var conversionOpCode = ConversionOpCodeTable[(int)toTypeCode, (int)fromTypeCode]; if (conversionOpCode == OpCodes.Nop) { return; } if (conversionOpCode == OpCodes.Throw) { // Guid cannot be resolved from ConversionOpCodeTable. if (ReferenceEquals(from, typeof(Guid)) && ReferenceEquals(to, typeof(Guid))) { return; } // byte[] cannot be resolved from ConversionOpCodeTable. if (ReferenceEquals(from, typeof(object)) && ReferenceEquals(to, typeof(byte[]))) { return; } // char[] cannot be resolved from ConversionOpCodeTable. if (ReferenceEquals(from, typeof(object)) && ReferenceEquals(to, typeof(char[]))) { return; } il.Emit(OpCodes.Ldstr, ThrowException.InvalidCast(from, to)); il.Emit(OpCodes.Newobj, typeof(InvalidCastException).GetConstructor(Type.EmptyTypes)); il.Emit(OpCodes.Throw); } if (fromTypeCode == TypeCode.Boolean) { ConvertFromBoolean(il, conversionOpCode); return; } if (toTypeCode == TypeCode.Boolean) { ConvertToBoolean(il, conversionOpCode); return; } if (fromTypeCode == TypeCode.Decimal) { il.Emit(OpCodes.Call, DecimalMetadata.GetConversionMethodFromDecimal(toTypeCode)); return; } if (toTypeCode == TypeCode.Decimal) { il.Emit(OpCodes.Call, DecimalMetadata.GetConversionMethodToDecimal(fromTypeCode)); return; } if ((fromTypeCode == TypeCode.UInt32 || fromTypeCode == TypeCode.UInt64) && (toTypeCode == TypeCode.Single || toTypeCode == TypeCode.Double)) { il.Emit(OpCodes.Conv_R_Un); } il.Emit(conversionOpCode); }