传递给函数时但不是本地的列表元素出现意外的不等式

问题描述

我正在尝试实现一个比较不同列表元素的功能。我不断收到意外的行为,显然是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,};

    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一个类,具有Harmony库中的opcode {System.Reflection.Emit.OpCode}和operand {object}字段的类。

解决方法

CodeInstruction class source code操作数字段中的

是object类型。

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

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

您的第二个比较是引用等于,将为false。

// 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