一个类型必须同时重写Equals方法和GetHashCode方法是因为System.Collections.Hashtable类型的实现要求任何两个相等的对象都必须有相同的散列码值.所以如果我们重写了Equals方法,我们也应该重写GetHashCode方法以确保用来判等的算法和用来计算对象散列码的算法一致.
基本上来讲,当我们向一个Hashtable对象中添加一个"键/值对"时,其中"键对象"的散列码会首先被获取.该散列码指出了"键/值对"应该被存储在哪个"散列桶(Bucket)"中.当Hashtable对象需查找某个"键"时,它会取得指定"键对象"的散列码.然后在该散列码所标识的那个"散列桶"中进一步查找和指定的"键对象"相等的"键对象".使用这种存储和搜索"键"的算法意味着如果我们改变了Hashtable中的一个"键对象",我们在Hashtable中将不再找到该对象.
实现一个GetHashCode方法可以相当容易.但是,根据我们的数据类型的数据的分布,如果要得到一个数值范围分布良好的散列算法,还需要一些技巧.下面是一个简单的例子,对于Point对象来说可能已经足够了:
class Point {
Int32 x, y;
public override Int32 GetHashCode() {
return x^y; //对x和y做异或操作
}
}
当选择计算类型实例的散列码算法时,我们应该尽力遵循以下原则:
算法应该使所得的数值有一个良好的随机分布,这样散列表可以获得最佳的性能.
算法还可以调用基类型的GetHashCode方法,并将其返回值包含在我们自己的算法中。但一般情况下,我们不应该调用Object或者valueType的GetHashCode方法,因为这两个