Question

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;
        ...
    }
}
Était-ce utile?

La 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.

Autres conseils

For any floating point number Equals and == behave differently.

  • NaN==NaN => false following IEEE logic
  • NaN.Equals(NaN) => true Follwing the requirement that anything must be equal to itself.

And of course Equals is overridden i.e. it works even when the static type is a base type, whereas == is overloaded and only works if the static type has been overloaded.

I almost never call x.Equals(y) directly. For one it doesn't handle a x being null, and it's asymmetry is ugly IMO. The static object.Equals(x,y) calls the virtual object.Equals(y) method, but adds null handling.

IEquatable<T>.Equals(other) is equivalent to object.Equals(other) on all well behaved types, but it avoids boxing in value types.

In conclusion I usually prefer == when the static type is known, and EqualityComparer<T>.Default with generic types or if the static type doesn't match the runtime type.


In your example Name and Id behave the same way with == and Equals, since string and int are sealed.

TheObject on the other hand exhibits different behavior with == and Equals for certain types. For example if you use string then Equals will use value equality, and == will use reference equality.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top