如何将实例化的对象与其原始对应对象进行匹配

时间:2019-05-16 12:12:59

标签: c# unity3d

我想要的是能够将一个项目的副本与其原始副本匹配。我尝试运行的代码如下所示。我想检查库存中的物品是否与手工系统所需的物品匹配。这两个项目是相同的,唯一的区别是我的库存中的项目(左)是原件的副本,而我的制作系统中的项目是原件(右)。

下面的代码是stringbuilder的一部分。在运行时,它将显示玩家所需的物品数量以及制作工艺所需的物品数量。如果我使用原始项目而不是其副本,则该代码有效,但是由于我获取的是项目副本而不是其原始副本,因此我不知道如何进行此检查。

我尝试匹配它们的名称,但是那根本不起作用,团结抛出了空引用异常。我已经进行了大约6到7个月的编程,但是还不太熟练。我在这些事情上经常陷入困境,如果有人能帮助我,我将不胜感激。

if (Icont.islots[i].item == reci.Materials[0].item)
{
    sb0.Length = 0;
    Itemslot0(Icont.islots[i].item.amount, reci.Materials[0].amount);
    iteminfo[0].text = sb0.ToString();
}

我尝试过的事情是,匹配名称,匹配id,在两侧使用副本,但是所有这些都在我的脸上抛出了null引用异常。如果您考虑一下,这是显而易见的,因为每个副本都有自己的ID,因此它们将不匹配,但是我对于为什么无法使用它们的名称匹配对象感到困惑。

1 个答案:

答案 0 :(得分:1)

您的问题出在这一行:if (Icont.islots[i].item == reci.Materials[0].item)

由于您要比较的项目是reference types(我假设它们是“类”),因此您使用默认的==运算符将进行引用相等性检查(除非您对其进行了重载,似乎您还没有)。

这意味着==将检查两个项目是否是对内存中同一对象的引用。这就是为什么您看到期望的行为的原因,而当一个仅仅是另一个的克隆时就会看到不期望的行为的原因。

您可以通过多种方式解决此问题;您可以将项目类型更改为value typeStruct),可以重载==运算符,可以使用自定义相等比较,然后列表将继续。

我个人要做的是创建一个自定义的相等比较函数,该函数本质上说“如果这些属性相同,则项目1等于项目2”。

一个小例子是:

public static bool IsEqualTo(this Item thisItem, Item otherItem)
{
    if (thisItem is null) return otherItem is null;
    else if (otherItem is null) return thisItem is null;

    return thisItem.property1 == otherItem.property1
        && thisItem.property2 == otherItem.property2
        && thisItem.property3 == otherItem.property3;
}

然后只需更改

if (Icont.islots[i].item == reci.Materials[0].item)

if (Icont.islots[i].item.IsEqualTo(reci.Materials[0].item))

此方法使您可以控制如何定义相等性。例如,您可能会说游戏中的每个不同项目都有一些Id属性,该属性对于该项目类型是唯一的。如果是这种情况,那么您的IsEqualTo()方法只需要返回两个对象是否具有相同的ID。

编辑:正如@ScottHannen在评论中所说,如果您收到NullReferenceException,则表示您所引用的项之一实际上并未初始化。确保两个项目上所需的每个对象和属性都已实际初始化。