64位HashCodes,IEqualityComparer&相交/除

时间:2014-11-11 21:05:11

标签: c# hashcode gethashcode iequalitycomparer

我正在从字符串生成64位哈希码,并将此值存储在数据库中

是否可以使用64位长类型而不是32字节int覆盖GetHashCode?

如果无法做到这一点,是否可以在其他地方实现Equals和GetHashCode,仍然使用Except和Intersect?

public class RecordComparer : IEqualityComparer<Record>
{
    public bool Equals(Record x, Record y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (x == null || y == null) return false;
        return x.RecordHash.Equals(y.RecordHash);
    }

    public long GetHashCode(Record obj)
    {
        return obj.RecordHash;
    }
 }

2 个答案:

答案 0 :(得分:1)

内置集合,算法和接口都不支持64位哈希码。你必须自己建造一切。您需要一个完整的并行基础架构。

这可能会变得不值得。相反,使用32位哈希码并依赖于您的相等比较,以确保不会发生错误匹配。无论如何,这是正确性所必需的。

也许这个问题是基于一个误解:

  

基本上我将有2个64位哈希码整数列表。一世   需要能够在这两个列表中使用Except / Intersect来查找   差异,基于64位hascode值。一切都是如此,   IEqualityComparer仅适用于32位整数。

只需将此哈希码视为内置集合和算法中的关键字。您可以使用Except处理这些列表。

答案 1 :(得分:0)

假设您不关心由具有相同哈希码的不同记录引起的可能问题,因此即使它们不同也被认为是相同的,您可以像这样简单地实现RecordComparer

public class RecordComparer : IEqualityComparer<Record>
{
    public bool Equals(Record x, Record y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (x == null || y == null) return false;
        return x.RecordHash.Equals(y.RecordHash);
    }

    public int GetHashCode(Record obj)
    {
        return unchecked((int) obj.RecordHash);
    }
}

IEqualityComparer<T>通过返回通过截断标识记录的64位哈希码创建的32位哈希码来正确实现。

不要求GetHashCode应为不相等的记录返回唯一的哈希码。但是,避免冲突会使像Dictionary<Record>这样的通用集合表现更好,并且基于64位哈希码的32位哈希码可能是最好的事情。

如果你查看Enumerable.ExceptEnumerable.Intersect的源代码,你可以看到他们使用内部类Set<T>这是一种哈希表,所以你的{{1}的实现可以影响代码的性能但不影响正确性(只要相等的记录返回相同的哈希码)。