Правила 1 и 3 противоречат мне.
В определенной степени, они есть. Причина проста: если объект хранится в хеш-таблице и, изменяя его значение, вы изменяете его хеш, тогда хеш-таблица теряет значение, и вы не можете найти его снова, запросив хеш-таблицу. Важно, что хотя объекты хранятся в хеш-таблице, они сохраняют свое хеш-значение.
Чтобы осознать это, зачастую проще сделать неизменяемые объекты, что позволяет избежать всей проблемы. Однако достаточно сделать неизменными только те поля, которые определяют значение хеш-функции.
Рассмотрим следующий пример:
struct Person {
public readonly string FirstName;
public readonly string Name;
public readonly DateTime Birthday;
public int ShoeSize;
}
Люди редко меняют свой день рождения, и большинство людей никогда не меняют свое имя (кроме случаев, когда они вступают в брак). Однако размер их обуви может увеличиваться произвольно или даже уменьшаться. Поэтому разумно идентифицировать людей, используя их день рождения и имя, но не их размер обуви. Значение хеша должно отражать это:
public int GetHashCode() {
return FirstName.GetHashCode() ^ Name.GetHashCode() ^ Birthday.GetHashCode();
}