Как сопоставить экземпляр объекта с его оригинальным аналогом - PullRequest
1 голос
/ 16 мая 2019

Что мне нужно, так это возможность сопоставить копию предмета с его оригинальной копией.Код, который я пытаюсь запустить, показан ниже.Я хочу проверить, соответствует ли предмет, который у меня есть в инвентаре, предмету, который требует моя система крафта.Оба предмета одинаковы, единственное отличие состоит в том, что предмет в моем инвентаре (слева) - это копия оригинала, а предмет в моей системе крафта - оригинал (справа).

Приведенный ниже код является частью строителя строк.Во время выполнения он показывает игроку, сколько предметов он того типа, который требуется, и сколько ему нужно для крафта.Код работает, если я использую оригинальный элемент, а не его копию, но, поскольку я получаю копии элементов, а не их оригинал, я не знаю, как выполнить эту проверку.

Я пытался сопоставить их имена, но это совсем не работает, из-за единицы выбрасывается исключение нулевой ссылки.Я занимаюсь программированием около 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();
}

То, что я пробовал, - это сопоставление имен, совпадений идентификаторов, использование копий с обеих сторон, но все они выбрасывают исключительную ссылку на мое лицо.Если вы думаете об этом, это очевидно, потому что каждая копия получает свой собственный идентификатор, и поэтому они не будут совпадать, но я не понимаю, почему я не могу сопоставить объект, используя их имена.

1 Ответ

1 голос
/ 16 мая 2019

Ваша проблема заключается в этой строке: if (Icont.islots[i].item == reci.Materials[0].item)

Поскольку элементы, которые вы сравниваете, являются ссылочными типами (я предполагаю, что они являются "классами"), то использование оператора == по умолчанию будет выполнять проверку на равенство ссылок (если вы не перегрузите его, что кажется, что нет).

Это означает, что == проверит, являются ли два элемента ссылкой на один и тот же объект в памяти. Вот почему вы видите желаемое поведение, когда они есть, и нежелательное поведение, когда один просто является клоном другого.

Существует множество способов решить эту проблему; Вы можете изменить тип элемента на тип значения (a Struct), вы можете перегрузить оператор ==, вы можете использовать пользовательское сравнение на равенство и список можно продолжить.

Что бы я лично сделал, так это создал бы пользовательскую функцию сравнения на равенство, которая по существу говорит: «Элемент 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() просто должен возвращать, имеют ли оба объекта одинаковый идентификатор.

РЕДАКТИРОВАТЬ: Как сказал @ScottHannen в комментариях, если вы получаете NullReferenceException, то это означает, что один из элементов, на который вы ссылаетесь, на самом деле не был инициализирован. Убедитесь, что каждый необходимый вам объект и свойство на обоих элементах действительно инициализированы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...