简体   繁体   English

C#用户类。 GetHashCode实现

[英]C# User class. GetHashCode implementation

I have simple class only with public string properties. 我只有公共字符串属性的简单类。

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

This code doesn't return same value for equal instances. 对于相等的实例,此代码不会返回相同的值。 But this class does not have readonly fields for compute hash. 但是此类没有用于计算哈希的只读字段。

How can i generate correct hash in GetHashCode() if all my properties are mutable. 如果我所有的属性都是可变的,我该如何在GetHashCode()生成正确的哈希。

The contract for GetHashCode requires (emphasis mine): 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方法返回值的对象状态,对象的GetHashCode方法就必须始终返回相同的哈希码。

So basically, you should compute it based on all the used fields in Equals , even though they're mutable. 因此,基本上,您应该根据Equals所有使用的字段进行计算,即使它们是可变的。 However, the documentation also notes: 但是,文档还指出:

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 ,则文档应明确说明,当对象存储在哈希表中时,该类型的用户不应修改对象值。

If only some of your properties were mutable, you could potentially override GetHashCode to compute it based only on the immutable ones - but in this case everything is mutable, so you'd basically end up returning a constant, making it awful to be in a hash-based collection. 如果只有部分属性是可变的,则可以覆盖GetHashCode以仅基于不可变的属性进行计算-但是在这种情况下, 所有内容都是可变的,因此您最终将返回一个常量,使它变得难以处理基于哈希的集合。

So I'd suggest one of three options: 因此,我建议以下三个选项之一:

  • Use the mutable fields, and document it carefully. 使用可变字段,并仔细记录下来。
  • Abandon overriding equality/hashing operations 放弃覆盖平等/哈希操作
  • Abandon it being mutable 放弃它的可变性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM