我会避免这样做,因为它会毫无意义地创建一堆字符串 - 尽管 Kosi2801 关于使碰撞变得简单的观点也很重要。(我怀疑它实际上不会产生很多碰撞,由于字段的性质,但是......)
我会选择我之前在这个答案中使用过的“简单易懂”的算法(感谢您查找 lance :) - 正如您所说,它列在 Effective Java 中。在这种情况下,它将最终成为:
public int GetHashCode()
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + StreetAddress.GetHashCode();
hash = hash * 23 + RuralRoute.GetHashCode();
hash = hash * 23 + City.GetHashCode();
hash = hash * 23 + Province.GetHashCode();
hash = hash * 23 + Country.GetHashCode();
hash = hash * 23 + PostalCode.GetHashCode();
return hash;
}
当然,这不是空安全的。如果您使用 C# 3,您可能需要考虑扩展方法:
public static int GetNullSafeHashCode<T>(this T value) where T : class
{
return value == null ? 1 : value.GetHashCode();
}
然后你可以使用:
public int GetHashCode()
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + StreetAddress.GetNullSafeHashCode();
hash = hash * 23 + RuralRoute.GetNullSafeHashCode();
hash = hash * 23 + City.GetNullSafeHashCode();
hash = hash * 23 + Province.GetNullSafeHashCode();
hash = hash * 23 + Country.GetNullSafeHashCode();
hash = hash * 23 + PostalCode.GetNullSafeHashCode();
return hash;
}
您可以创建一个参数数组方法实用程序以使其更加简单:
public static int GetHashCode(params object[] values)
{
int hash = 17;
foreach (object value in values)
{
hash = hash * 23 + value.GetNullSafeHashCode();
}
return hash;
}
并调用它:
public int GetHashCode()
{
return HashHelpers.GetHashCode(StreetAddress, RuralRoute, City,
Province, Country, PostalCode);
}
在大多数类型中都涉及到原语,因此会在某种程度上不必要地执行装箱,但在这种情况下,您只有引用。当然,你最终会不必要地创建一个数组,但你知道他们对过早优化的说法......