1

Equals(T x, T y)关于 IEqualityComparer,除了我下面的内容之外,是否有任何理由说明实现应该是什么?

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();
    }
}
4

4 回答 4

4

是的。哈希码可能会发生冲突,事实上,它们会与多种类型发生冲突。它们的存在只是为了确保哈希表中值的均匀分布,它们对于确定值的相等性没有用。Eric Lippert对此也有看法(还有另一个):

使用 32 位哈希码作为“唯一”标识符是一个非常糟糕的主意。哈希值本身不是随机的,但如果它们分布良好,那么它们也可能是我们的目的。你可能会想“嗯,当然,显然它们并不是真正唯一的,因为有超过 40 亿个可能的值,但只有 40 亿个哈希码可用。但是有这么多可能的哈希值,很有可能我会得到我的哈希值的唯一值”。但机会真的那么好吗?9300 个对象并不多,1% 是相当高的碰撞概率。

话虽如此,如果您的 ID 是您在确定相等性时唯一关心的事情,那么比较该 ID 就足够了。但不是它的哈希码,因为哈希码只说

a .GetHashCode() ≠ b .GetHashCode() → ab

请注意,没有提及哈希码相同的情况。

于 2013-04-17T15:42:33.853 回答
2

是的,有:如果ID的哈希码不适合int,现在或将来的某个时间,当具有相同哈希码的不相等对象开始评估为相等时,您会感到非常惊讶。如果以后有人决定ID应该是longor GuidMyEquality将继续愉快地编译,但它的行为将是完全不正确的。

在一个不相关的注释中,如果MyType是一个类,您可能想要在x或是y时做一些防止崩溃的事情null:尽管合同IEqualityComparer<T>没有明确要求它(不像那样),但在情况下object.Equals处理nulls是个好主意IEqualityComparer<T>.Equals当您搜索可能包含null对象的容器时。

于 2013-04-17T15:43:02.913 回答
0

当然。您可能有一个对象,您只关心一个或多个属性是否相同,以便出于您的目的将它们视为相等。

于 2013-04-17T15:44:46.367 回答
0

如果您要比较 List list1 和 List list2,如果它们有一些“共同”元素,例如 list1={"apparent", "obvious"} 和 list2={"aPPARENT", "oBVIOUS"}

如果您对股权的定义如下:

  • 第一个字符必须相等,区分大小写
  • 余数字符不能相等(区分大小写)

您必须在 IEqualityComparer 中定义自己的逻辑。

此外,在 LINQ 中,所有Where、Any、Except、Intersect等子句可能需要额外的 IEqualityComparer 对象来挂钩您的自定义逻辑。

于 2013-04-17T15:45:36.450 回答