如果我正在实现IEquatable <T>,重写Equals是否重要?

naw*_*fal 7 c# generics equality iequatable

我知道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);
}
Run Code Online (Sandbox Code Playgroud)

sup*_*cat 10

未密封的类型不应该实现IEquatable<T>,因为确保(或甚至使其可能)派生类型将正确实现它的唯一方法是实现IEquatable<T>.Equals(T)以便调用Object.Equals(Object).由于整个目的IEquatable<T>是为了避免浪费CPU时间将事物转换为Object比较它们之前,调用的实现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>应考虑相互独立.虽然通常情况是,当X.CompareTo(Y)为零时,X.Equals(Y)将返回true,但某些类型可能具有自然顺序,其中两个事物可能不同而没有对另一个进行排名.例如,一个人可能有一个NamedThing<T>组合a string和a 的类型T.这样的类型将支持名称的自然排序,但不一定支持T.两个实例,其名称匹配,但他们T的不同应该返回0CompareTo,但falseEquals.因此,如果不更改,则覆盖IComparable不需要覆盖.GetHashCodeEquals


Ode*_*ded 6

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

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

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

myObject1.Equals((object)myObject2); // false!
Run Code Online (Sandbox Code Playgroud)

另一个可能的问题是继承类 - 如果将类型与继承类型进行比较,则很容易失败.


naw*_*fal 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)等需要。

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