我为我的一个类重写了Equals方法。在方法中,我检查每对字典与另一个实例的字典的相等性,如下所示
public override bool Equals (object obj)
{
...
// compare to make sure all <key, value> pair of this.dict have
// the match in obj.dict
...
}
现在,我需要覆盖GetHashCode方法以及建议的内容。
我是否需要为字典的所有键,或键加值?
基本上,以下是好还是矫枉过正?
public override int GetHashCode ()
{
int iHash = 0;
foreach (KeyValuePair<string, T> pair in this.dict)
{
iHash ^= pair.Key.GetHashCode();
iHash ^= pair.Value.GetHashCode();
}
return iHash;
}
答案 0 :(得分:1)
与@Mitch Wheat链接的一起,如果你将这个类与Dictionary或HashSet一起使用,这不是做GetHashCode()的最好方法。
想象一下,你的内部词典只有一个条目。您的哈希值现在是该单个KeyValuePair
的值。你把全班都放在HashSet
中。您将另一个项目添加到内部Dictionary
。现在你的类的哈希码已经改变,因为你正在迭代你班上的两个项目。
当您致电HashSet.Contains(obj)
时,它会调用现已更改的obj.GetHashCode()
,即使它是同一个类实例。 HashSet.Contains()
会发现它不包含这个新哈希并返回false,从不调用Equals(如果引用相同,则返回true)。
突然间它就像你的对象已经从HashSet中消失了,即使该类在那里,还有一个过时的哈希。
您真的不希望您的哈希值发生变化。可以在GetHashCode
中进行冲突,因为如果它发生碰撞,它将调用(较慢的).Equals()
方法。这是一个方便的优化,如果实施不当,可能会引起一些麻烦。
作为旁注,正如上面链接中所指出的,最好将散列乘以^
之前的素数和另一个值。帮助保持独特性。
答案 1 :(得分:0)
您打算在HashSet中使用该对象吗?如果要以这样的方式使用对象,它需要通过其散列进行唯一标识,那么实际上只需要实现GetHashCode。 是 的好习惯,总是实现GetHashCode,同时考虑到相同使用的相同字段,但并非总是必要。
如果您的情况有必要,我相信您有正确的想法。