c# - 如果我正在实现 IEquatable<T>,那么覆盖 Equals 是否重要?

标签 c# generics equality iequatable

我知道重写 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/

相关文章:

c# - 如何使用泛型变量执行数学运算?

关于 Equals 实现的 C# 不同 MSDN 指南

java - 如何在 Java 中比较字符串?

c# - 如果子类型是父类型

c# - 引用摘要验证失败

c# - 将 appSetting 写入单独的 *.config 文件

c# - 在 windows mobile 6 上双指缩放

java - Mockito:使用泛型列出匹配器

c# - 如何知道这是循环的最后一次迭代?

python - 元组比较 'A' == ('A' ),如何避免这种情况?