我知道重写 GetHashCode
的重要性在实现自定义相等性检查时 - 我已经为此实现了 IEquality<T>
接口(interface),以及通用和非通用之间的区别Equals
as discussed here.现在有必要覆盖 Equals(object t)
吗? ?难道一切都不会属于通用Equals(T t)
吗? ?
public override int GetHashCode() //required for hashsets and dictionaries
{
return Id;
}
public bool Equals(T other) //IEquatable<T> here
{
return Id == other.Id;
}
public override bool Equals(object obj) //required??
{
return Equals(obj as T);
}
最佳答案
未密封类型不应实现 IEquatable<T>
,因为确保(甚至可能)派生类型正确实现它的唯一方法是实现 IEquatable<T>.Equals(T)
以便调用Object.Equals(Object)
.由于 IEquatable<T>
的全部目的是为了避免浪费 CPU 时间将事物转换为 Object
在比较它们之前,一个调用 Object.Equals(Object)
的实现如果未实现接口(interface),则无法比默认行为更快地执行任何操作。
密封类类型可以通过实现 IEquatable<T>
获得轻微的性能优势;首选样式是 Object.Equals(Object)
尝试将参数转换为 T
;如果转换成功,使用 IEquatable<T>.Equals
执行;否则返回 false
.在任何情况下都不应 IEquatable.Equals(T)
和 Object.Equals(Object)
传递相同的对象实例时产生不同的结果。
结构类型可以使用与密封类类型相同的模式。尝试转换的方法有点不同,因为失败的转换不能返回 null
,但模式应该还是一样的。如果一个结构实现了一个可变接口(interface)(例如 List<T>.Enumerator
,一个实现了 IEnumerator<T>
的结构),相等比较的正确行为就有点模糊了。
请注意,顺便说一句,IComparable<T>
和 IEquatable<T>
应该被认为是相互独立的。虽然通常情况下 X.CompareTo(Y)
为零,X.Equals(Y)
将返回 true,某些类型可能具有自然排序,其中两件事可能不同,但没有对另一件事进行排名。例如,一个人可能有一个 NamedThing<T>
结合了 string
的类型和一个 T
.这样的类型将支持名称的自然排序,但不一定支持 T
。 .名称匹配但 T
的两个实例的不同应该返回 0
对于 CompareTo
,但是false
对于 Equals
.因此,覆盖 IComparable
不需要覆盖 GetHashCode
如果Equals
没有改变。
关于c# - 如果我正在实现 IEquatable<T>,那么覆盖 Equals 是否重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13741737/