private static void EmitNumericConversion(this ILGenerator ilGenerator, Type typeFrom, Type typeTo, bool isChecked) { var isFromUnsigned = TypeInfoUtils.IsUnsigned(typeFrom); var isFromFloatingPoint = TypeInfoUtils.IsFloatingPoint(typeFrom); if (typeTo == typeof(float)) { if (isFromUnsigned) { ilGenerator.Emit(OpCodes.Conv_R_Un); } ilGenerator.Emit(OpCodes.Conv_R4); } else if (typeTo == typeof(double)) { if (isFromUnsigned) { ilGenerator.Emit(OpCodes.Conv_R_Un); } ilGenerator.Emit(OpCodes.Conv_R8); } else { TypeCode tc = typeTo.GetTypeCode(); if (isChecked) { // Overflow checking needs to know if the source value on the IL stack is unsigned or not. if (isFromUnsigned) { switch (tc) { case TypeCode.SByte: ilGenerator.Emit(OpCodes.Conv_Ovf_I1_Un); break; case TypeCode.Int16: ilGenerator.Emit(OpCodes.Conv_Ovf_I2_Un); break; case TypeCode.Int32: ilGenerator.Emit(OpCodes.Conv_Ovf_I4_Un); break; case TypeCode.Int64: ilGenerator.Emit(OpCodes.Conv_Ovf_I8_Un); break; case TypeCode.Byte: ilGenerator.Emit(OpCodes.Conv_Ovf_U1_Un); break; case TypeCode.UInt16: case TypeCode.Char: ilGenerator.Emit(OpCodes.Conv_Ovf_U2_Un); break; case TypeCode.UInt32: ilGenerator.Emit(OpCodes.Conv_Ovf_U4_Un); break; case TypeCode.UInt64: ilGenerator.Emit(OpCodes.Conv_Ovf_U8_Un); break; default: throw new InvalidCastException(); } } else { switch (tc) { case TypeCode.SByte: ilGenerator.Emit(OpCodes.Conv_Ovf_I1); break; case TypeCode.Int16: ilGenerator.Emit(OpCodes.Conv_Ovf_I2); break; case TypeCode.Int32: ilGenerator.Emit(OpCodes.Conv_Ovf_I4); break; case TypeCode.Int64: ilGenerator.Emit(OpCodes.Conv_Ovf_I8); break; case TypeCode.Byte: ilGenerator.Emit(OpCodes.Conv_Ovf_U1); break; case TypeCode.UInt16: case TypeCode.Char: ilGenerator.Emit(OpCodes.Conv_Ovf_U2); break; case TypeCode.UInt32: ilGenerator.Emit(OpCodes.Conv_Ovf_U4); break; case TypeCode.UInt64: ilGenerator.Emit(OpCodes.Conv_Ovf_U8); break; default: throw new InvalidCastException(); } } } else { switch (tc) { case TypeCode.SByte: ilGenerator.Emit(OpCodes.Conv_I1); break; case TypeCode.Byte: ilGenerator.Emit(OpCodes.Conv_U1); break; case TypeCode.Int16: ilGenerator.Emit(OpCodes.Conv_I2); break; case TypeCode.UInt16: case TypeCode.Char: ilGenerator.Emit(OpCodes.Conv_U2); break; case TypeCode.Int32: ilGenerator.Emit(OpCodes.Conv_I4); break; case TypeCode.UInt32: ilGenerator.Emit(OpCodes.Conv_U4); break; case TypeCode.Int64: if (isFromUnsigned) { ilGenerator.Emit(OpCodes.Conv_U8); } else { ilGenerator.Emit(OpCodes.Conv_I8); } break; case TypeCode.UInt64: if (isFromUnsigned || isFromFloatingPoint) { ilGenerator.Emit(OpCodes.Conv_U8); } else { ilGenerator.Emit(OpCodes.Conv_I8); } break; default: throw new InvalidCastException(); } } } }