c# - 使用 xor 的 GetHashCode() 问题

标签 c# .net gethashcode

我的理解是,您通常应该将 xor 与 GetHashCode() 结合使用来生成一个 int 以通过其值(而不是通过其引用)来标识您的数据。这是一个简单的例子:

class Foo
{
    int m_a;
    int m_b;

    public int A
    {
        get { return m_a; }
        set { m_a = value; }
    }

    public int B
    {
        get { return m_b; }
        set { m_b = value; }
    }

    public Foo(int a, int b)
    {
        m_a = a;
        m_b = b;
    }

    public override int GetHashCode()
    {
        return A ^ B;
    }

    public override bool Equals(object obj)
    {
        return this.GetHashCode() == obj.GetHashCode();
    }
}

我的想法是,我想根据属性 A 和 B 的值将 Foo 的一个实例与另一个实例进行比较。如果 Foo1.A == Foo2.A 和 Foo1.B == Foo2.B,那么我们就相等.

问题是:

Foo one = new Foo(1, 2);
Foo two = new Foo(2, 1);

if (one.Equals(two)) { ... }  // This is true!

它们都为 GetHashCode() 生成值 3,导致 Equals() 返回 true。显然,这是一个简单的示例,只有两个属性,我可以简单地比较 Equals() 方法中的各个属性。但是,对于更复杂的类,这会很快失控。

我知道有时候只设置哈希码一次并始终返回相同的值是很有意义的。但是,对于需要进行相等性评估的可变对象,我认为这是不合理的。

处理在实现 GetHashCode() 时可以轻松互换的属性值的最佳方法是什么?

See Also

What is the best algorithm for an overridden System.Object.GetHashCode?

最佳答案

首先 - 不要仅根据 GetHashCode() 实现 Equals() - 即使对象不相等,哈希码有时也会发生冲突。

GetHashCode() 的契约(Contract)包括以下内容:

  • 不同的哈希码意味着对象肯定不相等
  • 相同的哈希码意味着对象可能相等(但也可能不相等)

Andrew Hare 建议我合并他的回答:

我建议您阅读 this solution (顺便说一下,我们自己的 Jon Skeet )用于计算哈希码的“更好”方法。

No, the above is relatively slow and doesn't help a lot. Some people use XOR (eg a ^ b ^ c) but I prefer the kind of method shown in Josh Bloch's "Effective Java":

public override int GetHashCode()
{
    int hash = 23;
    hash = hash*37 + craneCounterweightID;
    hash = hash*37 + trailerID;
    hash = hash*37 + craneConfigurationTypeCode.GetHashCode();
    return hash;
}

The 23 and 37 are arbitrary numbers which are co-prime.

The benefit of the above over the XOR method is that if you have a type which has two values which are frequently the same, XORing those values will always give the same result (0) whereas the above will differentiate between them unless you're very unlucky.

正如上面代码片段中提到的,您可能还想查看 Joshua Bloch's book, Effective Java,其中包含对该主题的很好处理(哈希码讨论也适用于 .NET)。

关于c# - 使用 xor 的 GetHashCode() 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1008633/

相关文章:

c# - 流通过

c# - 从 Controller 的类中获取 MVC Controller 名称

c# - 覆盖具有 'dibs' 的类型的 Equals 和 GetHashCode?

c# - 覆盖可变对象的 GetHashCode?

c# - 从 asp.net mvc 4 razor 中的自定义 Html Helpers 访问属性

c# - 由于名称相同,无法添加引用

c# - sql server 缓存问题

.net - 如何从我的 DLL 访问 MainForm 中的函数

c# - 卢塞恩 : very slow NRT performance

C# 如何根据对象引用计算哈希码