Ejemplo n.º 1
0
        public static void GenerateJumpIfEqual(ILGenerator ilGenerator, Type type, Label jumpTo, Action <ILGenerator> loadLeft, Action <ILGenerator> loadRight)
        {
            if (type == typeof(sbyte) || type == typeof(byte) || type == typeof(short) || type == typeof(ushort) ||
                type == typeof(int) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong) ||
                type == typeof(float) || type == typeof(double) || type == typeof(bool))
            {
                loadLeft(ilGenerator);
                loadRight(ilGenerator);
                ilGenerator.BeqS(jumpTo);
                return;
            }
            if (type.IsGenericType)
            {
                var genType = type.GetGenericTypeDefinition();
                if (genType == typeof(Nullable <>))
                {
                    var localLeft      = ilGenerator.DeclareLocal(type);
                    var localRight     = ilGenerator.DeclareLocal(type);
                    var hasValueMethod = type.GetMethod("get_HasValue");
                    var getValueMethod = type.GetMethod("GetValueOrDefault", Type.EmptyTypes);
                    loadLeft(ilGenerator);
                    ilGenerator.Stloc(localLeft);
                    loadRight(ilGenerator);
                    ilGenerator.Stloc(localRight);
                    var labelLeftHasValue = ilGenerator.DefineLabel();
                    var labelDifferent    = ilGenerator.DefineLabel();
                    ilGenerator
                    .Ldloca(localLeft)
                    .Call(hasValueMethod)
                    .BrtrueS(labelLeftHasValue)
                    .Ldloca(localRight)
                    .Call(hasValueMethod)
                    .BrtrueS(labelDifferent)
                    .BrS(jumpTo)
                    .Mark(labelLeftHasValue)
                    .Ldloca(localRight)
                    .Call(hasValueMethod)
                    .BrfalseS(labelDifferent);
                    GenerateJumpIfEqual(
                        ilGenerator,
                        type.GetGenericArguments()[0],
                        jumpTo,
                        g => g.Ldloca(localLeft).Call(getValueMethod),
                        g => g.Ldloca(localRight).Call(getValueMethod));
                    ilGenerator.Mark(labelDifferent);
                    return;
                }
            }
            var equalsMethod = type.GetMethod("Equals", new[] { type, type })
                               ?? type.GetMethod("op_Equality", new[] { type, type });

            if (equalsMethod != null)
            {
                loadLeft(ilGenerator);
                loadRight(ilGenerator);
                ilGenerator
                .Call(equalsMethod)
                .BrtrueS(jumpTo);
                return;
            }
            throw new NotImplementedException(String.Format("Don't know how to compare type {0}", type));
        }