4

我找到了一个看起来像这样的 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 方法吗?

4

2 回答 2

2

从 MSDN(实施者注意事项部分)

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

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

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

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

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

更多精彩阅读

于 2012-10-17T21:29:58.257 回答
1

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

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

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

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

希望有帮助

于 2012-10-17T21:31:45.297 回答