7

我知道在实现自定义相等检查时覆盖的重要性GetHashCode——我已经实现了接口,以及这里讨论IEquality<T>的泛型和非泛型之间的区别。现在有需要覆盖的地方吗?一切都不是通用的吗?Equals 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);
}
4

3 回答 3

10

未密封的类型不应该实现IEquatable<T>,因为确保(甚至可能)派生类型正确实现它的唯一方法是实现IEquatable<T>.Equals(T)以调用Object.Equals(Object). 由于 的全部目的IEquatable<T>是避免Object在比较它们之前浪费 CPU 时间来转换事物,因此调用的实现Object.Equals(Object)无法比未实现接口时实现的默认行为更快地执行任何操作。

密封类类型可以通过实现来获得轻微的性能优势IEquatable<T>;首选样式是Object.Equals(Object)尝试将参数转换为T; 如果转换成功,则使用IEquatable<T>.Equals实现;否则返回false。在传递相同的对象实例时,在任何情况下都不应产生不同的IEquatable.Equals(T)结果。Object.Equals(Object)

结构类型可以使用与密封类类型相同的模式。尝试转换的方法有点不同,因为失败的转换不能返回null,但模式应该仍然相同。如果一个结构实现了一个变异接口(例如List<T>.Enumerator,一个实现 的结构IEnumerator<T>),相等比较的正确行为有点模糊。

请注意,顺便说一句,IComparable<T>应该IEquatable<T>被认为是相互独立的。虽然经常会出现 when X.CompareTo(Y)is 0X.Equals(Y)会返回 true 的情况,但某些类型可能具有自然排序,其中两个事物可能不同,而没有一个关于另一个事物的排名。例如,一个人可能有一种NamedThing<T>结合了 astring和 a的类型T。这种类型将支持 name 的自然排序,但不一定支持T. 两个名称匹配但T不同的实例应该返回0for CompareTo,但是falsefor Equals。因此,如果未更改,则覆盖IComparable不需要覆盖。GetHashCodeEquals

于 2012-12-06T19:47:49.573 回答
6

您当然应该覆盖Equals(object t)- 否则在使用该重载时您可能会得到不正确的结果。您不能假设 theEquals(T other)是将被调用的重载。

如果您不覆盖它,将使用引用相等,这意味着类似以下内容将返回 false:

myObject1.Id = 1;
myObject2.Id = 1;

myObject1.Equals((object)myObject2); // false!

另一个可能的问题是继承类——如果你将你的类型与继承类型进行比较,这很容易失败。

于 2012-12-06T10:35:46.777 回答
3

来自msdn

如果您实现 IEquatable,您还应该重写 Object.Equals(Object) 和 GetHashCode 的基类实现,以便它们的行为与 IEquatable.Equals 方法的行为一致。如果您确实重写了 Object.Equals(Object),那么在调用类上的静态 Equals(System.Object, System.Object) 方法时也会调用您重写的实现。此外,您应该重载 op_Equality 和 op_Inequality 运算符。这可确保所有相等性测试返回一致的结果。

我也可以做一个更好的谷歌搜索。这是JaredPar 在 msdn 博客上关于该主题的一篇好文章。

简而言之,压倒一切Equals(object obj)

对象类上的静态Equals(object obj1, object obj2)方法或ArrayList实例上的 Contains(object item) 等需要

接受这一点,因为该链接在该主题上更加详尽。也感谢奥德..

于 2012-12-06T10:51:35.500 回答