C# 用户 class。 GetHashCode 实现

C# User class. GetHashCode implementation

我有简单的 class 只有 public 字符串属性。

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!
    }
}

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

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

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

The GetHashCode method for an object must consistently return the same hash code as long as there is no modification to the object state that determines the return value of the object's Equals method.

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

If you do choose to override GetHashCode for a mutable reference type, your documentation should make it clear that users of your type should not modify object values while the object is stored in a hash table.

如果您的属性中只有 一些 是可变的,您可以覆盖 GetHashCode 以仅基于不可变的属性来计算它 - 但在这种情况下 一切都是可变的,所以你基本上最终会返回一个常量,这使得在基于散列的集合中变得很糟糕。

所以我建议以下三个选项之一:

  • 使用可变字段,并仔细记录。
  • 放弃覆盖 equality/hashing 操作
  • 放弃它是可变的