Расширение C # Equals не может проверить равенство - PullRequest
0 голосов
/ 24 октября 2018

Я расширил метод equals и hashcode, чтобы проверить равенство двух идентичных объектов с логическими свойствами.когда я изменяю объект, делая одно из логических свойств ложным вместо истинного, он не распознает разницу и утверждает, что они равны;Есть идеи почему?

   public override bool Equals(object value)
    {
        if (!(value is LocationPropertyOptions options))
            return false;

        return Equals(options, value);
    }

    public bool Equals(LocationPropertyOptions options)
    {
        return options.GetHashCode() == GetHashCode();
    }

    public override int GetHashCode()
    {
        return ToString().GetHashCode();
    }

    public override string ToString()
    {
        return $"{Identifier}{AccountEntityKey}{Address}{Comments}{Contact}" +
               $"{Coordinate}{Description}{FaxNumber}{LastOrderDate}{PhoneNumber}" +
               $"{ServiceAreaOverride}{ServiceRadiusOverride}{StandardInstructions}" +
               $"{WorldTimeZone_TimeZone}{ZoneField}{CommentsOptions}";
    }

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Это на самом деле не отвечает на ваш вопрос.Однако при реализации равенства следует учитывать несколько моментов, чтобы избежать ошибок такого рода.

Сначала у вас есть две совершенно разные реализации для обозначения равенства.Ваш override bool Equals(object value) перенаправляет на статический метод Object.Equals(object, object), который просто выполняет ReferenceEquals.С другой стороны, ваша public bool Equals(LocationPropertyOptions) (вероятно, реализация для IEquatable<LocationPropertyOptions>) просто использует вашу странную реализацию GetHashCode, то есть

Пункт два: вам не следует использовать изменяемый член в вашей реализации хеш-кодав частности, когда ваши объекты хранятся в словаре или хэш-карте, что сильно зависит от хорошей реализации хеш-кода.См. MSDN для GetHashCode

Вы можете переопределить GetHashCode () для неизменяемых ссылочных типов.В целом, для изменяемых ссылочных типов вы должны переопределять GetHashCode () только в том случае, если:

  • Вы можете вычислить хэш-код из полей, которые не являются изменяемыми;или

  • Вы можете гарантировать, что хеш-код изменяемого объекта не изменится, пока объект содержится в коллекции, которая использует свой хеш-код.

Третий и последний: вы не должны использовать GetHashCode в проверке на равенство:

Не проверять на равенство хеш-кодов, чтобы определить, равны ли два объекта

Хотя предполагается, что равные объекты имеют одинаковые хеш-коды, в любом случае разные объекты могут иметь одинаковый хеш-код.Для этого равный хеш-код - это просто индикатор , что два экземпляра могут быть равными.

Два равных объекта возвращают одинаковые хеш-коды.Однако обратное неверно: одинаковые хеш-коды не подразумевают равноправие объектов, поскольку разные (неравные) объекты могут иметь одинаковые хеш-коды [...]
Не следует предполагать, что равные хеш-коды подразумевают равенство объектов.

0 голосов
/ 24 октября 2018

Вы разыгрываете options из value, затем звоните Equals с options против value.Это означает, что вы сравниваете value с value, он всегда возвращает true для вас

public override bool Equals(object value)
{
    if (!(value is LocationPropertyOptions options))
       return false;    
    return Equals(options, value);
}

Попробуйте сравнить this с value, например

return Equals(this, value);
...