Чтобы добавить к ответу Джона, я бы просто добавил акцент на определенную часть документов, которые вы цитировали:
Метод GetHashCode для объекта должен последовательно возвращать тот же хеш-код, поканет никакого изменения в состоянии объекта , которое определяет возвращаемое значение метода Equals объекта .
Теперь, прямо здесь вы нарушили правила.Вы изменили PK
, что не влияет на результат Equals
(потому что у вас там есть ReferenceEquals
проверка), но результат вашего GetHashCode
влияет менять.Так что это простой ответ.
Используя более концептуальный подход, я думаю, вы можете посмотреть на это так: если у вас есть переопределенное поведение Equals
и GetHashCode
для вашего типазатем вы взяли на себя ответственность за понятие , что означает, что один экземпляр этого типа равен другому .И на самом деле вы определили его таким образом, что объект Hashable
можно заменить на что-то совершенно другое ;то есть что-то, что больше нельзя использовать таким же образом, как это было раньше (потому что его хеш-код изменился).
Рассматривается с этой точки зрения после того, как вы выполните dict.Add(h, true)
, а затем измените h.PK
,словарь больше не содержит объект, на который ссылается h
.Он содержит что-то иначе (которого на самом деле нигде нет).Это похоже на тип, который вы определили как змея, которая сбросила свою кожу.