编写一个好的 GetHashCode 覆盖

GetHashCode 对 Dictionary <>和 HashTable 有重要的性能影响。

好的 GetHashCode 方法

  • 应该有均匀的分布
    • 每个整数应该具有大致相等的返回随机实例的机会
    • 如果你的方法为每个实例返回相同的整数(例如常量'999’),你将会有不好的表现
  • 应该很快
    • 这些不是加密哈希,其中慢是一个特征
    • 哈希函数越慢,字典就越慢
  • 必须在 Equals 计算为 true 的两个实例上返回相同的 HashCode
    • 如果他们不这样做(例如因为 GetHashCode 返回一个随机数),则可能无法在 ListDictionary 或类似物品中找到物品。

实现 GetHashCode 的一个好方法是使用一个素数作为起始值,并将类型字段的哈希码加上其他素数乘以:

public override int GetHashCode()
{
    unchecked // Overflow is fine, just wrap
    {
        int hash = 3049; // Start value (prime number).

        // Suitable nullity checks etc, of course :)
        hash = hash * 5039 + field1.GetHashCode();
        hash = hash * 883 + field2.GetHashCode();
        hash = hash * 9719 + field3.GetHashCode();
        return hash;
    }
}

只有 Equals 方法中使用的字段才应用于散列函数。

如果你需要以不同的方式为 Dictionary / HashTables 处理相同的类型,则可以使用 IEqualityComparer。