Search code examples
c#.netiequatableequals-operatorobject-equality

Difference between Object.Equals(objA, objB), objA.Equals(objB) and objA == objB for CLR types?


I am wondering if the CLR types would return different results from the following:

Object.Equals(objA, objB)

objA.Equals(objB)

(objA == objB)

I do realize that outside of the CLR someone could easily implement the IEqualtable Equals and overload the == operator improperly. I'm not concerned with people improperly implementing these. What I'm concerened with is the classes (including String, Int32, etc) implement these 3 differently.

Also, which one should be the one used for comparison overall (across the board) if that is possible. I wonder this because I ran across a file that uses Object.Equals(objA, objB) all over a view-model instead of the other two.

private string _name;
public string Name
{
    get { return _name; }
    set
    {
        if (Equals(_name, value)) return;
        ...
    }
}

private int _id;
public int Id
{
    get { return _id; }
    set
    {
        if (Equals(_id, value)) return;
        ...
    }
}

private Object _obj;
public Object TheObject
{
    get { return _obj; }
    set
    {
        if (Equals(_obj, value)) return;
        ...
    }
}

Solution

  • Object.Equals(a,b) is null safe. It can answer e.g. Equals(null, null) which is true. Apart from that, it just calls the regular Equals() method. As far as I know the clr string and primitive types have equality operators defined that work exactly like Object.Equals(a,b).

    For non-null objA and objB, Object.Equals(objA, objB), objA.Equals(objB) and objB.Equals(objA) should be equivalent if the Equals method is correctly implemented.

    The use of Equals(_obj, value) seems correct in the code you posted.

    If you want the complete list of equality comparisons, don't forget about objA.ReferenceEquals(objB) which is a kind of equality that is useful in many scenarios.