コード例 #1
0
        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();
                    }
                }
            }
        }