gpt4 book ai didi

c# - 我应该使用我的字符串字段的串联作为哈希码吗?

转载 作者:可可西里 更新时间:2023-11-01 07:56:17 24 4
gpt4 key购买 nike

我在 C# 中有一个 Address 类,如下所示:

public class Address
{
public string StreetAddress { get; set; }
public string RuralRoute { get; set; }
public string City { get; set; }
public string Province { get; set; }
public string Country { get; set; }
public string PostalCode { get; set; }
}

我正在实现相等性,因此我需要覆盖哈希码。起初我打算使用 EJ 的哈希码公式,但后来我想:这些都是字符串字段,我不能只使用 StringBuilder 连接它们并从该字符串返回哈希码吗?

即:

var str = new StringBuilder();
str.Append(StreetAddress)
.Append(RuralRoute)
...

return str.ToString().GetHashCode();

这样做的优点/缺点是什么?我为什么不应该这样做?

最佳答案

我会避免这样做,因为它会毫无意义地创建一堆字符串——尽管 Kosi2801 关于简化碰撞的观点也很重要。 (由于场的性质,我怀疑它实际上不会产生很多碰撞,但是...)

我会选择我之前使用的“简单易行”算法 used in this answer (感谢您查找 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);
}

在大多数类型中,都涉及基元,因此这会在某种程度上不必要地执行装箱,但在这种情况下,您只有引用。当然,你最终会不必要地创建一个数组,但你知道他们怎么说过早优化......

关于c# - 我应该使用我的字符串字段的串联作为哈希码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/957588/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com