我知道在实现自定义相等性检查时覆盖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
所浪费的CPU时间,因此调用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/