Предупреждение: «… заменяет Object.Equals (object o), но не отменяет Object.GetHashCode ()»

Я переопределил Equals () моего класса для сравнения значений идентификаторов типа Guid.

Затем Visual Studio предупредила:

... переопределяет Object.Equals (object o), но не отменяет Object.GetHashCode ()

Итак, я также переопределил его GetHashCode () следующим образом:

public partial class SomeClass
{
    public override bool Equals(Object obj)
    {
        //Check for null and compare run-time types.
        if (obj == null || this.GetType() != obj.GetType()) return false;

        return this.Id == ((SomeClass)obj).Id;
    }

    public override int GetHashCode()
    {
        return this.Id.GetHashCode();
    }
}

Кажется, он работает. Правильно ли я сделал это? Помните, что Id имеет тип Guid. Имеет ли значение, что мой класс является объектом Entity Framework?

25
задан Zack Peterson 24 June 2011 в 21:19
поделиться

3 ответа

Как уже говорили другие, использование Reflection in Equals кажется хитрым. Оставляя это в стороне, давайте сосредоточимся на GetHashCode.

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

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

Я предполагаю, что «Id» является неизменным свойством. Если «Id» может меняться в течение всего времени жизни объекта, тогда у вас могут возникнуть проблемы при помещении объекта в хеш-таблицу. Подумайте о том, чтобы при вычислении равенства и хеш-кода использовались только неизменяемые свойства.

Ваша реализация выглядит хорошо, но тот факт, что вы задаете вопрос, указывает на то, что вы можете не иметь четкого представления обо всех тонких факторах, влияющих на создание реализации GetHashCode. Хорошее место для начала - моя статья на эту тему:

http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

33
ответ дан 28 November 2019 в 20:33
поделиться

Поскольку вы не имеете дело с запечатанным классом, я бы рекомендовал не проверять равенство классов, как это this.GetType() != obj.GetType(). Любой подкласс SomeClass также должен иметь возможность участвовать в Equals, поэтому вы можете использовать это вместо:

if (obj as SomeClass == null) return false;
6
ответ дан 28 November 2019 в 20:33
поделиться

Вы получили отличные ответы на свой первый вопрос:

Правильно ли я это сделал?

Я отвечу на ваш второй вопрос

Имеет ли значение, что мой класс является объектом Entity Framework?

Да, это очень важно. Entity Framework использует HashSet много внутри. Например, динамические прокси используют HashSet для представления навигационных свойств коллекции и EntityObject используют EntityCollection, который, в свою очередь, использует HashSet для внутреннего использования.

5
ответ дан 28 November 2019 в 20:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: