重写Equals和GetHashCode并不一定会覆盖相等重载运算符

时间:2017-05-18 06:07:09

标签: c#

我有以下代码:

public enum ClassType
{
    I,
    II,

}

public enum LocationType
{
    A,
    B
}
public class Person
{
    public LocationType LocType
    { get; set; }
    public ClassType ClaType
    { get; set; }


    public override bool Equals(object obj)
    {
        Person obPer = obj as Person;
        if (obPer == null)
            return false;
        if (LocType != obPer.LocType)
            return false;
        if (ClaType != obPer.ClaType)
            return false;
        return true;

    }

    public override int GetHashCode()
    {
        return LocType.GetHashCode()^ClaType.GetHashCode();
    }

}

  static void Main(string[] args)
    {

        var p1 = new Person()
        {
            ClaType = ClassType.I,
            LocType = LocationType.A
        };


        var p2 = new Person()
        {
            ClaType = ClassType.I,
            LocType = LocationType.A
        };

        bool isEqual1 = p1.Equals(p2);  //true
        bool getHashCodeNum = p1.GetHashCode() == p2.GetHashCode();  //true
        bool isEqual2 = p1 == p2;  //false
    }

我发现isEqual1=truegetHashCodeNum=true,但是isEqual2=false

我希望由于我已经覆盖EqualsGetHashCode,因此运算符==应该自动遵循Equals的行为,但事实并非如此。有什么原因吗?

1 个答案:

答案 0 :(得分:5)

==运算符。您可以重载 ==运算符超过两个Person,如下所示:

public class Person {

    //..

    public static bool operator == (Person a, Person b)
    {
        if (Object.ReferenceEquals(a,null) && Object.ReferenceEquals(b,null))
            return true;
        if (Object.ReferenceEquals(a,null) || Object.ReferenceEquals(a,null))
            return false;
        return a.LocType == b.LocType && a.ClaType != b.ClaType;
    }

    public static bool operator != (Person a, Person b)
    {
       return ! (a == b);
    }

}

==!=是成对的:如果您实施!=,则需要实施==,反之亦然,否则您会收到错误:

  

错误CS0216:运营商Person.operator ==(Person, Person)要求定义匹配的运营商!=

现在,当你比较两个Person时,它应该有效。但是请注意,会覆盖相等运算符,重载它们。所以编译器选择==实现(这是在运行时通过动态绑定完成)。结果:

bool isEqual2 = p1 == p2;  //true
bool isEqual3 = (object) p1 == p2;  //false
bool isEqual4 = p1 == (object) p2;  //false
bool isEqual5 = (object) p1 == (object) p2;  //false

默认情况下,==超过两个object引用相等所以只有当这两个参数都是Person时,我们才会检查这两个人等同于

因此,如果要使用动态绑定检查相等性,最好使用Equals(..)