0

I am trying to implement a function that compares elements of different lists. I keep getting unexpected behavior, where apparently OpCodes.Brfalse != OpCodes.Brfalse or 12 != 12.

It only seems to exhibit this behavior when I pass lists of items as parameters to a function that compares their individual elements, not when I compare them locally.

[TestMethod()]
public void findListMatch_TEST()
{
    var alist = new List<Harmony.CodeInstruction>()
    {
        new Harmony.CodeInstruction(OpCodes.Brfalse, 12),
    };
    var blist = new List<Harmony.CodeInstruction>()
    {
        new Harmony.CodeInstruction(OpCodes.Brfalse, 12),
    };

    Assert.AreEqual(alist[0].opcode, blist[0].opcode); //Passes
    Assert.AreEqual(alist[0].operand, blist[0].operand); //Passes

    Assert.IsTrue(Foo(alist, blist)); //Fails
}

bool Foo(List<Harmony.CodeInstruction> alist, List<Harmony.CodeInstruction> blist)
{
    var A = alist[0];
    var B = blist[0];

    if (A.opcode != B.opcode)
    {
        return false; //Hit this sometimes, expect not to
    }
    else if (A.operand != B.operand)
    {
        return false; //Hit this sometimes, expect not to
    }
    return true;
}

Harmony.CodeInstruction is a class with fields opcode {System.Reflection.Emit.OpCode} and operand {object} from the Harmony library.

Jonqora
  • 3
  • 1
  • What happen when you do `Assert.IsTrue(alist[0].opcode == blist[0].opcode)` and `Assert.IsTrue(alist[0].operand == blist[0].operand)` – Chetan Sep 07 '20 at 02:28

1 Answers1

0

in CodeInstruction class source code operand field is of type object.

So your first comparison checks for equality using Object.Equals method

// Uses Object.Equals
Assert.AreEqual(alist[0].operand, blist[0].operand); 

Your second comparison is reference equals which will be false.

// Reference comparison will be false because both are boxing value 12 in different memory locations.
A.operand != B.operand

You can easily test this in a simple console application

object a = 12;
object b = 12;
Console.WriteLine(a.Equals(b)); // True
Console.WriteLine(a == b); // False
Sherif Elmetainy
  • 4,034
  • 1
  • 13
  • 22