How to implement IEquatable<T> when mutable fields are part of the equality - Problem with GetHashCode

假装没事ソ 提交于 2019-12-02 07:27:05

You've used a mutable field (AddressId) as part of the hash - that is unfortunately doomed. By which I mean: when you add it, the AddressId is 0? -1? it doesn't matter what exactly, but it isn't the final id - and it is stored with this key / hash. When you save it, the actual id (the IDENTITY column from the database) is updated into the object.

Quite simply, you cannot reliably hash against this value if it can change when it is part of a dictionary. One possible workaround would be to consider the unit-of-work, i.e. an insert is a unit-of-work. Meaning: if the data etc only lives as long as this, then it is a non-issue as you will never attempt to access the data after saving it. Subsequently (in a different context) loading the data should be fine too, as the id doesn't then change during the lifetime.

Alternatively: drop this hash/equality.

Non-sealed classes should not implement IEquatable<T>, because the only way to ensure that a derived class which overrides Object.Equals() and Object.GetHashCode() will implement IEquatable<BaseType> in a fashion consistent with Object.GetHashCode() is for the interface implementation to call the virtual Object.Equals(Object) method. Since the only purpose of IEquatable<T> is to avoid the overhead of calling Object.Equals(Object), and a safe implementation of IEquatable<T> on an unsealed class cannot avoid calling it, such an implementation would serve no purpose.

Also, I would strongly counsel against any override of Object.Equals (or implementation of IEquatable<T>) for any mutable class type. It is good for structs, whether mutable or not, to override Object.Equals and Object.GetHashCode, and to implement IEquatable<theirOwnType>, since the fields of a struct stored as e.g. a Dictionary key will be immutable even if the struct type exposes mutable public fields.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!