C#用户类。 GetHashCode实现

时间:2016-12-24 11:35:46

标签: c# gethashcode

我只有公共字符串属性的简单类。

public class SimpleClass
{
    public string Field1 {get; set;}
    public string Field2 {get; set;}
    public string Field3 {get; set;}
    public List<SimpleClass> Children {get; set;}

    public bool Equals(SimpleClass simple)
    {
        if (simple == null)
        {
            return false;
        }
        return IsFieldsAreEquals(simple) && IsChildrenAreEquals(simple);
    }

    public override int GetHashCode()
    {
        return RuntimeHelpers.GetHashCode(this); //Bad idea!
    }
}

此代码不会为相等的实例返回相同的值。但是这个类没有用于计算哈希的只读字段。

如果我的所有属性都是可变的,我如何在GetHashCode()中生成正确的哈希值。

1 个答案:

答案 0 :(得分:7)

contract for GetHashCode要求(强调我的):

  

对象的GetHashCode方法必须始终返回相同的哈希码,只要不对对象状态进行修改即可确定对象的Equals方法的返回值

所以基本上,你应该根据Equals中所有使用的字段来计算它,即使它们是可变的。但是,文档还指出:

  

如果您确实选择覆盖GetHashCode以获取可变引用类型,那么您的文档应该清楚地表明,当对象存储在哈希表中时,您的类型的用户不应修改对象值。

如果只有某些属性是可变的,那么您可以覆盖GetHashCode来仅根据不可变的值来计算它 - 但在这种情况下所有是可变的,所以你基本上最终会返回一个常量,这使得在基于哈希的集合中变得非常糟糕。

所以我建议三种选择之一:

  • 使用可变字段,并仔细记录。
  • 放弃重写平等/散列操作
  • 放弃它是可变的