我该如何实现iqualitycomparer. equals ?
本文关键字:iqualitycomparer equals 实现 何实现 | 更新日期: 2023-09-27 18:09:35
关于IEqualityComparer,是否有理由认为Equals(T x, T y)
的实现应该是我下面所拥有的之外的任何东西?
public class MyEquality : IEqualityComparer<MyType>
{
//My Equals(T x, T y) always looks like this
public bool Equals(MyType x, MyType y)
{
return this.GetHashCode(x).Equals(this.GetHashCode(y));
}
public int GetHashCode(MyType obj)
{
//assume MyType has a non-nullable member called ID
return obj.ID.GetHashCode();
}
}
是。哈希码可能会发生冲突,事实上,它们会与许多类型发生冲突。它们的存在只是为了确保哈希表中值的均匀分布,它们对于确定值的相等性没有用处。Eric Lippert也对这个(和另一个)有一个看法:
使用32位哈希码作为"唯一"标识符是一个非常糟糕的主意。哈希值本身并不是随机的,但如果它们分布良好,那么它们也可能符合我们的目的。您可能会认为"当然,显然它们不是真正唯一的,因为有超过40亿个可能的值,但只有40亿个可用的哈希码。"但有这么多可能的哈希值,我很有可能得到唯一的哈希值"但机会真的那么好吗?9300个物体并不多,1%的碰撞概率相当高。
也就是说,如果你的ID是你在确定相等性时唯一关心的事情,那么比较那个ID就足够了。但不是它的哈希码,因为哈希码只表示
.GetHashCode()≠b .GetHashCode () →a≠b
请注意,对于哈希码相同的情况没有任何说明
是的,有:如果ID
的哈希码不适合int
,现在或将来的某个时候,当具有相同哈希码的不相等对象开始计算为相等时,您将面临一个令人讨厌的惊喜。如果在以后的日期有人决定ID
应该是long
或Guid
, MyEquality
将继续愉快地编译,但它的行为将是绝望的错误。
在一个不相关的注意事项上,如果MyType
是一个类,当x
或y
是null
时,您可能想要做一些事情来防止崩溃:尽管IEqualityComparer<T>
的契约没有显式调用它(不像object.Equals
那样),在IEqualityComparer<T>.Equals
中处理null
s是一个好主意,当您搜索可能包含null
对象的容器时。
当然。你可以有一个对象,你只关心一个或多个属性是相同的,认为它们是相等的,为您的目的。
如果你比较列表list1和列表list2,如果它们有一些"共同"的元素,例如list1={"apparent", "obvious"},和list2={" apparent", "obvious"}
如果你对权益的定义如下:
- 第一个字符必须相等,区分大小写
- 剩余字符不能相等(区分大小写)
你必须在你的IEqualityComparer中定义你自己的逻辑。
此外,在LINQ中,所有的Where, Any, Except, Intersect等子句可能需要额外的IEqualityComparer对象来挂钩您的自定义逻辑。