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

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

Object.Equals(objA, objB) objA.Equals(objB) (objA == objB) 

I understand that outside the CLR, someone can easily implement IEqualtable Equals and overload the == operator incorrectly. I am not interested in people who improperly implement them. What I agree with is that the classes (including String, Int32, etc.) implement these 3 differently.

In addition, which one should be used for comparison in general (across the board), if possible. Interesting because I came across a file that uses Object.Equals(objA, objB) for the whole view model, and not for 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; ... } } 
+4
source share
2 answers

Object.Equals (a, b) is null. He can answer, for example. Equals (null, null), which is true. In addition, it simply calls the regular Equals () method. As far as I know, clr string and primitive types have certain equality operators that work exactly the same as Object.Equals (a, b).

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

Using the Equals (_obj, value) code seems correct in the code you posted.

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

+6
source

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

  • NaN==NaN => false after IEEE logic
  • NaN.Equals(NaN) => true Follwing requires that something must be equal to itself.

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

I almost never call x.Equals(y) directly. For one, it does not handle x , which is null , and this asymmetry is an ugly IMO. The static object.Equals(x,y) calls the virtual object.Equals(y) method, but adds zero processing.

IEquatable<T>.Equals(other) equivalent to object.Equals(other) for all valid types, but it avoids boxing in value types.

In conclusion, I usually prefer == when the static type is known, and EqualityComparer<T>.Default with common types or if the static type does not match the runtime type.


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

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

+1
source

Source: https://habr.com/ru/post/1380217/


All Articles