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)); }