CompareTo()方法是否使用GetHashCode()
本文关键字:GetHashCode 方法 CompareTo 是否 | 更新日期: 2023-09-27 18:05:02
方法CompareTo()
是否使用GetHashCode()
为对象定义一个可比较的(而不是接口)编号?如果我做
MyObject.CompareTo(MyOtherObject.GetHashCode())
如果我不想重写CompareTo()
方法会发生什么?
不,CompareTo不/不应该使用GetHashCode来检查相等性。
他们可能(强调可能)使用它来确定不相等,如果哈希码被缓存,因此比比较所有内部数据更便宜,但是相等的哈希码并不一定意味着相等的对象。
如果你实现了Equals和GetHashCode(你需要同时实现或不实现),那么你应该遵循以下规则:
- 如果两个对象相等(Equals返回true),它们应该从GetHashCode产生相同的哈希码。你可以反过来说,如果两个GetHashCode方法返回不同的值,Equals应该返回false。
- 注意,反之不成立。如果Equals返回false,则GetHashCode返回相同的值是完全有效的,尽管通常不太可能。同样地,如果GetHashCode返回相同的值,那么Equals返回false是完全有效的,尽管通常也不太可能。这是因为鸽子洞原理(维基百科链接)。
- 始终使用相同的字段来检查是否相等并计算哈希码 不要使用可变字段(如果可以的话)。如果需要,请明确哪些字段将破坏哈希码和相等性检查。在哈希集或字典中填充可变对象并修改它们会破坏一切。
如果是你自己创建的对象,那么这里有一些规则:
- 如果需要排序支持,实现CompareTo和
IComparable<T>
。不要实现CompareTo 只有来获得相等性检查。 - 实现Equals, GetHashCode,和
IEquatable<T>
如果你需要相等性检查。
如果是不能修改的对象,创建:
-
IComparer<T>
支持排序 -
IEqualityComparer<T>
支持相等性检查
大多数将进行排序或相等性检查的集合或方法允许您指定一个额外的对象来确定排序或相等性检查的规则,假设对象内建的实现是错误的(可能只是在这个场景中)或缺失。
所有类型的链接:
-
System.IComparable<T>
和System.IComparer<T>
-
System.IEquatable<T>
和System.IEqualityComparer<T>