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

Gra*_*ton 2 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
    }
Run Code Online (Sandbox Code Playgroud)

我发现isEqual1=true,getHashCodeNum=trueisEqual2=false.

我希望,因为我已经覆盖EqualsGetHashCode,那么运营商==应该自动跟随的行为Equals,但事实并非如此.任何原因?

Wil*_*sem 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);
    }

}
Run Code Online (Sandbox Code Playgroud)

==并且!=是成对的:!=如果你实现你需要实现==,反之亦然,否则你会得到错误:

错误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
Run Code Online (Sandbox Code Playgroud)

默认情况下,==超过两个objects是引用相等,所以只有两个参数在Person这里,我们检查两个人是否相同.

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

  • if(a == null && b == null)将导致无限循环 (2认同)