2

I have the following code:

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
    }

I find that isEqual1=true, getHashCodeNum=true, but isEqual2=false.

I would expect that since I already override Equals and GetHashCode, then the operator == should automatically follow the behavior of Equals, but this is not so. Any reason?

Graviton
  • 81,782
  • 146
  • 424
  • 602
  • 1
    == only checks reference equality – Maxim Kosov May 18 '17 at 06:10
  • 2
    Since the language allows you to override `==` for your class, it doesn't do so behind the scenes if you choose not to. – Damien_The_Unbeliever May 18 '17 at 06:13
  • 1
    @Damien_The_Unbeliever: mind that you do **not** override, but *overload* the `==` operator. – Willem Van Onsem May 18 '17 at 06:16
  • You need to implement : public static bool operator ==(Person person1, Person person2) . Looks like same question be asked before in 2010: http://stackoverflow.com/questions/4219261/overriding-operator-how-to-compare-to-null – jdweng May 18 '17 at 06:18
  • You should overload the == (and the !=) operator as well . Follow [these](https://msdn.microsoft.com/en-us/library/ms173147(v=vs.90).aspx) guidelines – Ofir Winegarten May 18 '17 at 06:20

1 Answers1

5

An == is an operator. You can overload the == operator over two Persons as follows:

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);
    }

}

== and != are pairs: you need to implement != if you implement == and vice versa, otherwise you get the error:

error CS0216: The operator Person.operator ==(Person, Person) requires a matching operator != to also be defined

Now when you compare two Persons it should work. Mind however that you do not override equality operators, you overload them. So the compiler picks the == implementation (this is not done at runtime through a dynamic binding). As a result:

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

By default the == over two objects is reference equality so only if the two arguments are Persons here, we check whether the two persons are equivalent.

It is therefore probably better to use Equals(..) if you want to check equality with a dynamic binding.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • At this stage, I'd usually recommend implementing `IEquatable` too and putting all of the actual checks in there, as a central location. Then have `==` and `Equals(object)` call into it (after suitable `null` checks) – Damien_The_Unbeliever May 18 '17 at 06:19
  • 2
    if (a == null && b == null) will result in infinite loop – Maxim Kosov May 18 '17 at 06:20