重写GetHashCode()时使用Guid()。GetHashCode()有什么缺点

时间:2012-10-17 21:21:10

标签: c# dictionary equals gethashcode iequatable

我发现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方法吗?

2 个答案:

答案 0 :(得分:2)

From MSDN (Notes to Implementers section)

  

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

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

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

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

  6.   

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

More excellent reading

答案 1 :(得分:1)

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

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

如果对象更改,则计算的哈希值会有所不同。这对于数据验证通常很重要。如果我使用sha1将字符串'Frank'哈希到123456789(仅作为示例),并且我将数据与哈希一起发送给它们,它们可以执行相同的哈希并查看值是否匹配。如果我的位在发送时搞砸了,并且他们收到'Brank',当他们计算哈希时,它将不会是123456789,并且他们知道数据在发送时已损坏。

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

希望有所帮助