Jon*_*n B 9 .net c# 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();
}
}
Run Code Online (Sandbox Code Playgroud)
我的想法是,我想根据属性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!
Run Code Online (Sandbox Code Playgroud)
这些都为GetHashCode()生成值3,导致Equals()返回true.显然,这是一个简单的例子,只有两个属性,我可以简单地比较Equals()方法中的各个属性.然而,对于更复杂的类,这将很快失控.
我知道有时候只设置一次哈希码是很有意义的,并且总是返回相同的值.但是,对于需要对平等进行评估的可变对象,我认为这不合理.
在实现GetHashCode()时,处理易于互换的属性值的最佳方法是什么?
也可以看看
Mic*_*urr 27
首先 - 不要仅在GetHashCode()方面实现Equals() - 即使对象不相等,哈希码有时也会发生冲突.
GetHashCode()的合同包括以下内容:
Andrew Hare建议我加入他的答案:
我建议你阅读这个解决方案(通过我们自己的Jon Skeet,顺便说一句),以"更好"的方式来计算哈希码.
不,以上相对较慢,并没有多大帮助.有些人使用XOR(例如a ^ b ^ c),但我更喜欢Josh Bloch的"Effective Java"中显示的那种方法:
Run Code Online (Sandbox Code Playgroud)public override int GetHashCode() { int hash = 23; hash = hash*37 + craneCounterweightID; hash = hash*37 + trailerID; hash = hash*37 + craneConfigurationTypeCode.GetHashCode(); return hash; }23和37是任意数字,是共同素数.
上述优于XOR方法的好处是,如果你的类型有两个经常相同的值,那么对这些值进行异或将总是给出相同的结果(0),而上面将区分它们,除非你非常不走运.
正如上面的片段中所提到的,您可能还想看看Joshua Bloch的书"Effective Java",其中包含对该主题的一种很好的处理(哈希码讨论也适用于.NET).