传递给函数(但不是本地)时列表元素的意外不平等

Unexpected inequality for list elements when passed into a function (but not locally)

我正在尝试实现一个比较不同列表元素的函数。我不断收到意想不到的行为,显然 OpCodes.Brfalse != OpCodes.Brfalse12 != 12.

似乎只有当我将项目列表作为参数传递给比较它们的各个元素的函数时才会表现出这种行为,而不是当我在本地比较它们时。

[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 是一个 class,带有来自 Harmony 库的字段 opcode {System.Reflection.Emit.OpCode} 和 operand {object}。

CodeInstruction class source code 操作数字段是对象类型。

因此您的第一个比较使用 Object.Equals 方法检查是否相等

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

你的第二个比较是引用等于,这将是错误的。

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

您可以在简单的控制台应用程序中轻松测试它

object a = 12;
object b = 12;
Console.WriteLine(a.Equals(b)); // True
Console.WriteLine(a == b); // False