GetHashCode扩展方法

12 c# hash hashcode gethashcode

在阅读StackOverflow上有关覆盖的所有问题和答案之后,GetHashCode()我编写了以下扩展方法,以便轻松方便地覆盖GetHashCode():

public static class ObjectExtensions
{
    private const int _seedPrimeNumber = 691;
    private const int _fieldPrimeNumber = 397;
    public static int GetHashCodeFromFields(this object obj, params object[] fields) {
        unchecked { //unchecked to prevent throwing overflow exception
            int hashCode = _seedPrimeNumber;
            for (int i = 0; i < fields.Length; i++)
                if (fields[i] != null)
                    hashCode *= _fieldPrimeNumber + fields[i].GetHashCode();
            return hashCode;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

(我基本上只重构了有人在那里发布的代码,因为我真的很喜欢它可以一般使用)

我用的是这样的:

    public override int GetHashCode() {
        return this.GetHashCodeFromFields(field1, field2, field3);
    }
Run Code Online (Sandbox Code Playgroud)

你看到这段代码有什么问题吗?

Jon*_*upp 3

这看起来是一个可靠的方法。

我唯一的建议是,如果您真的关心它的性能,您可能需要为几种常见情况添加通用版本(即可能 1-4 个参数)。这样,对于这些对象(最有可能是小型的键样式复合对象),您将不需要构建数组以传递给方法、循环、任何泛型值装箱等的开销。调用语法将完全相同,但您将针对这种情况运行稍微优化的代码。当然,在您决定是否值得进行维护权衡之前,我会对此进行一些性能测试。

像这样的东西:

public static int GetHashCodeFromFields<T1,T2,T3,T4>(this object obj, T1 obj1, T2 obj2, T3 obj3, T4 obj4) {
    int hashCode = _seedPrimeNumber;
    if(obj1 != null)
        hashCode *= _fieldPrimeNumber + obj1.GetHashCode();
    if(obj2 != null)
        hashCode *= _fieldPrimeNumber + obj2.GetHashCode();
    if(obj3 != null)
        hashCode *= _fieldPrimeNumber + obj3.GetHashCode();
    if(obj4 != null)
        hashCode *= _fieldPrimeNumber + obj4.GetHashCode();
    return hashCode;
}
Run Code Online (Sandbox Code Playgroud)