2011-07-30 36 views
0

我重写了我的类之一的Equals方法。在该方法中,我检查每对字典的与另一个实例的字典中的平等,像下面这样做GetHashCode for Dictionary项目

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; 
} 
+2

http://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overriden-in-c –

+0

http://stackoverflow.com/questions/1378686/general-advice-and-guidelines-how-to-properly-override-object-gethashcode –

+0

你在为什么生成哈希码?这是您创建的自定义类吗?或者你是否将一个IEqualityComparer传递给现有的字典? –

回答

0

您是否打算在HashSet中使用该对象?如果对象的使用方式要求它可以通过散列唯一标识,那么只需要实现GetHashCode即可。它总是实施GetHashCode考虑到平等使用相同的字段,但并非总是必要的良好做法。

如果您的情况有必要,我相信您有正确的想法。

+0

很酷。这就是我想知道的。这纯粹是为了独特。 – tom

+0

很高兴我能帮到你。如果这对你来说是一个令人满意的答案,那么可以肯定的是,你将其标记为答案。 :) –

1

与@Mitch Wheat链接的内容不同,如果将此类与Dictionary或HashSet一起使用,则不是执行GetHashCode()的最佳方法。

想象一下,你的内部词典只有一个条目。您的散列值现在是单个的值KeyValuePair。你坚持全班上课HashSet。您将其他物品添加到您的内部Dictionary。现在你的类的哈希码已经改变了,因为你正在遍历你的类中的两个项目。

当您拨打HashSet.Contains(obj)时,它会调用obj.GetHashCode(),它现在已经更改,即使它的类实例相同。 HashSet.Contains()将发现它不包含这个新的散列并返回false,从不调用Equals(如果引用相同,将返回true)。

突然之间,它的像你的对象已经从HashSet中消失,即使类在那里,与过时的散列。

你真的不希望你的哈希值改变。可以在GetHashCode中发生碰撞,因为如果碰撞,它会调用(较慢).Equals()方法。这是一个方便的优化,如果执行不当,可能会导致一些头痛的问题。

作为一个方面说明,正如上面的链接所指出的,将散列与^之前的质数乘以另一个值是一个好主意。有助于保持独特性。

+0

这是一个有效的关注。如果字典是不可变的呢?那会不会出现你上面指出的问题? – tom

+0

如果Key/Value对永远不会改变,那么我的意思是没有'KeyValuePairs'被添加或删除,以及每个'KeyValuePair'的实际键和值不会被改变,那么是的,你会不必担心。请记住,在每个“KeyValuePair”中,键或值可以是一个类,并且该类可以是可变的,并且如果它被更改则输出不同的HashCode –