0

Object base class has the following code which compares equality of two objects

public static bool Equals(Object objA, Object objB) 
    {
        if (objA==objB) {
            return true;
        } 
        if (objA==null || objB==null) {
            return false; 
        } 
        return objA.Equals(objB);
    } 

What is the difference between comparisons objA==objB and objA.Equals(objB) and why do we need to check objA==objB separately?

UPDATE: The comment in the source code says that "Equality is defined as object equality for reference types and bitwise equality for value types". Thus if we deal with reference type and objA!=objB then we must return false without other comparisons, don't we? objA.Equals(objB) looks redundant here.

TOP KEK
  • 2,593
  • 5
  • 36
  • 62

4 Answers4

3

objA==objB checks for the reference equality where as objA.Equals(objB) can be overridden. So when references are equal then obviously we don't need to call Equals method which may perform value equality.

It is not necessary to compare for reference equality, I'd say it is an optimization, since value equality can be overridden and it may be expensive implementation which they(BCL team) wanted to optimize away when they know both are same references.

So this simply works on the fact that if references are equal then their values are also equal.

Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
3

The first comparison is a simple reference identity comparison - in other words, do the values of objA and objB refer to the same object (or are both null). This has two purposes in Equals(object, object):

  • It's an optimization so that when we compare an object with itself, we don't need to actually call Equals
  • This makes Equals(null, null) return true without having to have a special case for it

objA.Equals(objB) calls the virtual object.Equals(object) method, which can be overridden in subclasses. (An Equals implementation typically starts off with the same reference comparison as we've already performed, again for optimization purposes... it's a bit of a shame to have the same comparison twice, but it makes sense to avoid a virtual call when we don't need it.)

For example, string overrides Equals so that two independent string objects can still be equal to each other. (string also overloads the == operator to have the same meaning as Equals, but that's irrelevant in the Equals(object, object) code, as overloading is a compile-time matter... the == in Equals(object, object) will only ever perform a reference comparison.)

EDIT: The comment about "Equality is defined as object equality for reference types and bitwise equality for value types" is the default implementation of Equals (that's where the comment occurs). It has nothing to do with ==, and that behaviour can be overridden by overriding Equals further.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

== checks for reference equality. All types can override Equals method, so the purpose of calling objA.Equals(objB) is to compare objects based on custom implementation if there is any.

Selman Genç
  • 100,147
  • 13
  • 119
  • 184
1

The instance Equals() method is virtual and can be overridden in derived classes.

David Crowell
  • 3,711
  • 21
  • 28