Search code examples
c#classobjectequals

How do I check if an object is equal to a new object of the same class?


If I have a object like:

public class Person
{
    public int id {get;set;}
    public string name {get;set;}
}

And I want the behavior:

Person a = new Person();
Person b = new Person();

a == b;

and that a == b returns true, do I have to override the Object.Equals() method? or is there some other way of doing it without overriding the Equals method?

EDIT

I want to compare data, as I want to know if a external method that I call returns a new object or a object with different data than a new object


Solution

  • There are a couple of ways you can do this. By default Equals() and == check for reference equality, meaning:

    Person a = new Person();
    Person b = a:
    
    a.Equals(b); //true
    a == b; //true
    

    And therefore, the objects are not compared for value equality, meaning:

    Person a = new Person { id = 1, name = "person1" };
    Person b = new Person { id = 1, name = "person1" };
    
    a.Equals(b); //false
    a == b; //false
    

    To compare objects for their values you can override the Equals() and GetHashcode() methods, like this:

    public override bool Equals(System.Object obj)
    {
        if (obj == null)
            return false;
    
        Person p = obj as Person;
        if ((System.Object)p == null)
            return false;
    
        return (id == p.id) && (name == p.name);
    }
    
    public bool Equals(Person p)
    {
        if ((object)p == null)
            return false;
    
        return (id == p.id) && (name == p.name);
    }
    
    public override int GetHashCode()
    {
        return id.GetHashCode() ^ name.GetHashCode();
    }
    

    Now you will see other results when comparing:

    Person a = new Person { id = 1, name = "person1" };
    Person b = new Person { id = 1, name = "person1" };
    Person c = a;
    
    a == b; //false
    a == c; //true
    a.Equals(b); //true
    a.Equals(c); //true
    

    The == operator is not overridden and therefore still does reference comparison. This can be solved by overloading it as well as the != operator:

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

    Now running the checks results in following:

    Person a = new Person { id = 1, name = "person1" };
    Person b = new Person { id = 1, name = "person1" };
    Person c = a;
    
    a == b; //true
    a == c; //true
    a.Equals(b); //true
    a.Equals(c); //true
    

    More reading: