C#GetHashCode / Equals覆盖未调用

时间:2010-11-06 22:42:15

标签: c# operator-overloading

我遇到了GetHashCode和Equals的问题,我为一个类重写了它。我使用operator ==来验证两者是否相等,并且我希望如果它们的哈希码相同,则会调用GetHashCode和Equals以验证它们确实相等。

但令我惊讶的是,没有被调用,而且相等测试的结果是错误的(事实上它应该是真的)。​​

覆盖代码:

    public class User : ActiveRecordBase<User>

        [...]

        public override int GetHashCode()
        {
            return Id;
        }

        public override bool Equals(object obj)
        {
            User user = (User)obj;
            if (user == null)
            {
                return false;
            }

            return user.Id == Id;
        }
    }

平等检查:

    if (x == y) // x and y are both of the same User class
    // I'd expect this test to call both GetHashCode and Equals

2 个答案:

答案 0 :(得分:11)

运营商==.GetHashCode().Equals()完全分开。

您可能对Microsoft Guidelines for Overloading Equals() and Operator ==感兴趣。

简短版本是:使用.Equals()实施相等比较。使用运算符==进行标识比较,或者如果要创建不可变类型(可以认为每个相等的实例实际上相同)。此外,.Equals()是一个虚方法,可以被子类覆盖,但是运算符==取决于使用它的表达式的编译时类型。

最后,为了保持一致,请在实施.GetHashCode()时实施.Equals()。重载运算符!=时,重载运算符==

答案 1 :(得分:1)

或许在User课程中再添加一个方法。

    public virtual bool Equals(User other) 
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return other.Id == Id;
    }