【发布时间】:2023-03-08 17:12:01
【问题描述】:
Jon Skeet here 概述了实现 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;
}
}
手动滚动此代码很容易出错,并且错误可能很微妙/难以发现(您是否错误地交换了 + 和 *?),可能很难记住不同类型的组合规则,而且我不喜欢为不同的领域和课程一遍又一遍地写/审查同一件事。它还可以在重复噪声中混淆最重要的细节之一(我记得包括所有字段吗?)。
是否有使用 .net 库组合字段哈希码的简洁方法?。显然我可以自己写,但如果有一些惯用的/内置的东西,我会更喜欢。
例如,在 Java 中(使用 JDK7)我可以使用:
@Override
public int hashCode()
{
return Objects.hash(field1, field2, field3);
}
这确实有助于消除错误并专注于重要的细节。
动机:我遇到了一个需要重写 GetHashCode() 的 C# 类,但是它结合其各个组成部分的哈希码的方式存在一些严重的错误。用于组合哈希码的库函数将有助于避免此类错误。
【问题讨论】:
-
据我所知,最接近的方法是使用 ReSharper 进行相等成员和哈希码生成...
-
.NET 中的所有对象都实现了
GetHashCode(),如果你想将它们组合起来,只需将你想要使用的任何逻辑放在一个辅助方法中。 -
@evanmcdonnal,我不想写辅助方法。我希望其他人编写一个标准的辅助方法。具体来说,我希望有人编写一个 correct 辅助方法,以尽量减少编写(或维护者将其更改为)不正确实现的机会。以一种导致许多冲突的方式错误地组合哈希非常容易。
-
@HighCore,重写 hashcode/GetHashCode 的原因有很多。特别是,如果您覆盖 Equals 并且如果您的对象将成为哈希表中的键,则如果您想要合理的行为,则建议您这样做。 msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx
-
@bacar Hashtable was 8 years ago,你也需要一个很好的理由来覆盖
Equals()