【问题标题】:What are the drawbacks of using a Guid().GetHashCode() when overriding GetHashCode()覆盖 GetHashCode() 时使用 Guid().GetHashCode() 的缺点是什么
【发布时间】:2012-10-17 21:21:10
【问题描述】:

我找到了一个看起来像这样的 GetHashCode() 实现

    Guid _hashCode = Guid.NewGuid();
    public override int GetHashCode()
    {
        return _hashCode.GetHashCode();
    }

即使认为 Equals 看起来是正确的,说这种实现会导致许多关于 .NET 的假设被打破是否正确?

       public override bool Equals(object obj)
    {
        if (obj.GetType() != trustedEntity.GetType())
            return false;

        TrustedEntity typedObj = (TrustedEntity)obj;

        if (trustedEntity.BackTrustLink != typedObj.BackTrustLink)
            return false;
        if (trustedEntity.ForwardTrustLink != typedObj.ForwardTrustLink)
            return false;
        if (trustedEntity.EntryName != typedObj.EntryName)
            return false;

        return true;
    }

我听到的反驳论点是,一旦创建对象,GetHashCode 就不需要更改。这是因为此对象存储在字典中。

有人可以为我澄清一下,并解释如果对象发生更改,GetHashCode 需要发生什么,最终会更改 Equals 方法吗?

【问题讨论】:

  • 您尚未显示您的Equals。虽然两者都相关,但EqualsGetHashCode 并不相同。你的Equals 和这个Guid 比较吗?

标签: c# dictionary equals gethashcode iequatable


【解决方案1】:

From MSDN (Notes to Implementers section):

哈希函数必须具有以下属性:

  1. 如果两个对象比较相等,则每个对象的 GetHashCode 方法 对象必须返回相同的值。但是,如果两个对象不 比较相等,两个对象的 GetHashCode 方法不 必须返回不同的值。

  2. 对象的 GetHashCode 方法必须始终返回 只要对象状态没有修改,就具有相同的哈希码 确定对象的 Equals 方法的返回值。笔记 这仅适用于应用程序的当前执行, 如果应用程序是,则可以返回不同的哈希码 再次运行。

  3. 为了获得最佳性能,哈希函数必须生成随机 所有输入的分布。

根据此对象的 Equals 方法,您也可能违反了文档中的第一点。

More excellent reading

【讨论】:

【解决方案2】:

哈希是一种单向数学函数,它接受输入并提供可重现的输出。

哈希通常用于识别本身无法识别的数据,因此如果您对数据块计算哈希,则该数据应始终创建相同的哈希。一个例子是密码。当您注册网站时,他们会通过算法存储您密码的哈希值。当您登录时,您将密码发送到该站点,该站点使用与存储密码时使用的相同算法对其进行哈希处理。如果两个哈希值匹配,那么您输入了正确的密码。

如果对象发生变化,计算的哈希值会有所不同。这对于数据验证通常很重要。如果我使用 sha1 将字符串 'Frank' 散列为 123456789(只是一个示例),然后我将数据连同散列一起发送给他们,他们可以执行相同的散列并查看值是否匹配。如果我的位在发送时搞砸了,他们收到“Brank”,当他们计算哈希时,它不会是 123456789,他们知道数据在发送中被破坏了。

通过使用NewGuid,您只是在生成一个与原始数据无关的随机数。它不能被复制,所以上面的所有例子都是不可能的。哈希算法必须始终为相同的输入提供相同的输出,并且它还必须尝试防止任何其他输入生成相同的输出。

希望有帮助

【讨论】:

    猜你喜欢
    • 2012-07-13
    • 2010-09-11
    • 1970-01-01
    • 2010-09-20
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多