Почему рекомендуют переопределять GetHashCode и Equals вместе, хотя в своих программах нам не всегда нужны оба данных метода, а достаточно только переопределения одного из них, например, метода Equals.
Никогда не известно понадобится ли Вам или кому-либо еще данная реализация. Принято что при создании сложной логики, собственных структур данных Вы должны описать внутри структуры все краевые случаи работы, чтобы можно было в любой момент взять и воспользоваться без опаски что что-то может не работать.
Тогда у меня возникает следующий вопрос: как лучше всего реализовать переопределённый метод GetHashCode? Ведь Equals можно логически сверить состояние экземпляра, а GetHashCode должен возвращать уникальные значения для каждого нового экземпляра.
Видел несколько предложений по поводу переопределения метода GetHashCode.
1 способ:
взять два простых числа (например, 11 и 7) и проделать следующую процедуру:
public override int GetHashCode()
{
unchecked
{
int hash = 11;
hash = hash * 7 + field1.GetHashCode();
hash = hash * 7 + field2.GetHashCode();
// и так далее для всех существующих полей в классе
return hash;
}
}
2 способ:
поместить все поля в анонимный тип/ кортеж и вызвать на нём GetHashCode
public override int GetHashCode()
{
return new { field1, field2, field3 }.GetHashCode();
// return (field1, field2, field3).GetHashCode();
}
3 способ:
в случае если в классе 2 поля, то можно в качестве хешкода кода вернуть результат выполнения побитовой операции исключающее или над ними
public override int GetHashCode()
{
return field1 ^ field2;
}
Также можете почитать статью о хешовых функциях здесь.