我有一个类,其中包含许多我正在实现IEquitable<T>
的属性。我找到了关于如何为少量属性执行GetHashCode()的多个示例。
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;
}
}
当我在对象上有数百个属性时,我应该如何解决?
答案 0 :(得分:17)
花钱买Resharper之类的工具,然后做 Alt + Ins 然后 E 。这将打开“Generate Equality Members”对话框
从那里只需检查您需要的100个框,它将为您自动生成GetHashCode()
和Equals()
函数
(上面花了大约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对问题的评论中提出的问题并避免这种情况。部分原因可能是要考虑这些类型是否应该具有值语义(由它们的值定义的等价:是它们的属性值的集合),并切换到引用语义(每个实例都是唯一的)。