Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
        }