对具有大量属性的类实现GetHashCode()的最佳方法是什么?

时间:2014-05-05 09:03:05

标签: c# hashcode

我有一个类,其中包含许多我正在实现IEquitable<T>的属性。我找到了关于如何为少量属性执行GetHashCode()的多个示例。

Here is one example

public override int GetHashCode()
{
    unchecked // Overflow is fine, just wrap
    {
        int hash = 17;
        // Suitable nullity checks etc, of course :)
        hash = hash * 23 + field1.GetHashCode();
        hash = hash * 23 + field2.GetHashCode();
        hash = hash * 23 + field3.GetHashCode();
        return hash;
    }
}

当我在对象上有数百个属性时,我应该如何解决?

4 个答案:

答案 0 :(得分:17)

花钱买Resharper之类的工具,然后做 Alt + Ins 然后 E 。这将打开“Generate Equality Members”对话框

enter image description here

从那里只需检查您需要的100个框,它将为您自动生成GetHashCode()Equals()函数

enter image description here
(上面花了大约10秒钟创建)

Resharper做得更多,使得个人许可证价值150美元(你可以使用个人许可证进行与工作相关的活动,而不会违反它,我查了一下)。如果你作为程序员赚不到足够的钱来支付150美元的一次性投资,那么你真的应该开始寻找其他工作,因为你的工资很低。 (如果你在开源项目中没有为程序员赚钱,那么Resharper就是free for development teams of open source projects

答案 1 :(得分:6)

计算所有属性值的哈希码:

public override int GetHashCode()
{
    int hashCode = this.GetHashCodeOnProperties();
    return hashCode;
}

定义此扩展方法(可重用):

public static class HashCodeByPropertyExtensions
{
    public static int GetHashCodeOnProperties<T>(this T inspect)
    {
        return inspect.GetType().GetProperties().Select(o => o.GetValue(inspect)).GetListHashCode();
    }

    public static int GetListHashCode<T>(this IEnumerable<T> sequence)
    {
        return sequence
            .Where(item => item != null)
            .Select(item => item.GetHashCode())
            .Aggregate((total, nextCode) => total ^ nextCode);
    }
}

答案 2 :(得分:2)

也可以使用它。只是每次调用GetHash()的新实例的开销。

new { A = Prop1, B = Prop2, C = Prop3, D = Prop4 }.GetHashCode();

答案 3 :(得分:1)

如果所有这些属性都有助于对象的相等性(如果你没有覆盖相等性,为什么要覆盖GetHashCode?),那么他们需要在GetHashCode中包含所有这些属性。 / p>

记住等同对象必须具有相同的哈希码。

或许更好地解决Max对问题的评论中提出的问题并避免这种情况。部分原因可能是要考虑这些类型是否应该具有值语义(由它们的值定义的等价:是它们的属性值的集合),并切换到引用语义(每个实例都是唯一的)。