private static void EmitNumericConversion(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked) { if ( !(typeFrom.IsEnum || TypeUtil.IsNumeric(typeFrom)) || !(typeTo.IsEnum || TypeUtil.IsNumeric(typeTo)) ) { throw new InvalidOperationException("Unhandled convert"); } bool isFromUnsigned = TypeUtil.IsUnsigned(typeFrom); bool isFromFloatingPoint = TypeUtil.IsFloatingPoint(typeFrom); if (typeTo == typeof(Single)) { if (isFromUnsigned) { il.Emit(OpCodes.Conv_R_Un); } il.Emit(OpCodes.Conv_R4); } else if (typeTo == typeof(Double)) { if (isFromUnsigned) { il.Emit(OpCodes.Conv_R_Un); } il.Emit(OpCodes.Conv_R8); } else { TypeCode tc = Type.GetTypeCode(typeTo); 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: il.Emit(OpCodes.Conv_Ovf_I1_Un); break; case TypeCode.Int16: il.Emit(OpCodes.Conv_Ovf_I2_Un); break; case TypeCode.Int32: il.Emit(OpCodes.Conv_Ovf_I4_Un); break; case TypeCode.Int64: il.Emit(OpCodes.Conv_Ovf_I8_Un); break; case TypeCode.Byte: il.Emit(OpCodes.Conv_Ovf_U1_Un); break; case TypeCode.UInt16: case TypeCode.Char: il.Emit(OpCodes.Conv_Ovf_U2_Un); break; case TypeCode.UInt32: il.Emit(OpCodes.Conv_Ovf_U4_Un); break; case TypeCode.UInt64: il.Emit(OpCodes.Conv_Ovf_U8_Un); break; default: throw new InvalidOperationException("Unhandled convert"); } } else { switch (tc) { case TypeCode.SByte: il.Emit(OpCodes.Conv_Ovf_I1); break; case TypeCode.Int16: il.Emit(OpCodes.Conv_Ovf_I2); break; case TypeCode.Int32: il.Emit(OpCodes.Conv_Ovf_I4); break; case TypeCode.Int64: il.Emit(OpCodes.Conv_Ovf_I8); break; case TypeCode.Byte: il.Emit(OpCodes.Conv_Ovf_U1); break; case TypeCode.UInt16: case TypeCode.Char: il.Emit(OpCodes.Conv_Ovf_U2); break; case TypeCode.UInt32: il.Emit(OpCodes.Conv_Ovf_U4); break; case TypeCode.UInt64: il.Emit(OpCodes.Conv_Ovf_U8); break; default: throw new InvalidOperationException("Unhandled convert"); } } } else { switch (tc) { case TypeCode.SByte: il.Emit(OpCodes.Conv_I1); break; case TypeCode.Byte: il.Emit(OpCodes.Conv_U1); break; case TypeCode.Int16: il.Emit(OpCodes.Conv_I2); break; case TypeCode.UInt16: case TypeCode.Char: il.Emit(OpCodes.Conv_U2); break; case TypeCode.Int32: il.Emit(OpCodes.Conv_I4); break; case TypeCode.UInt32: il.Emit(OpCodes.Conv_U4); break; case TypeCode.Int64: if (isFromUnsigned) { il.Emit(OpCodes.Conv_U8); } else { il.Emit(OpCodes.Conv_I8); } break; case TypeCode.UInt64: if (isFromUnsigned || isFromFloatingPoint) { il.Emit(OpCodes.Conv_U8); } else { il.Emit(OpCodes.Conv_I8); } break; default: throw new InvalidOperationException("Unhandled convert"); } } } }