Comparing reference Types for equality
You might be surprised to learn thatSystem.Object defines three different methods for comparing objectsfor equality:ReferenceEquals()and two versions ofEquals(). Add to this the comparison operator(==), and you actually have four ways of comparing for equality. Some subtle differences exist between thedifferent methods, which are examined next.
The referenceequals() Method
ReferenceEquals() is a staticmethod that tests whether two references refer to the same instance
of a class, specifically whether the two references contain the same address in memory. As astaticmethod, it is not possible to override, so theSystem.Object implementation is what you always have.ReferenceEquals()will always returntrue if supplied with two references that refer to the same objectinstance, andfalse otherwise. It does, however, considernull to be equal tonull:
SomeClass x, y;
x = new SomeClass();
y = new SomeClass();
bool B1 = ReferenceEquals(null, null);bool B2 = ReferenceEquals(null,x);bool B3 = ReferenceEquals(x, y);
The virtual equals() Method
// returns true
// returns false
// returns false because x and y// point to different objects
The System.Objectimplementation of the virtual version ofEquals() also works by comparingreferences. However, because this method is virtual, you can override it in your own classes to compareobjects by value. In particular, if you intend instances of your class to be used as keys in a dictionary,
you will need to override this method to compare values. Otherwise, depending on how you overrideObject.GetHashCode(),the dictionary class that contains your objects will either not work at all or willwork very inefficiently. One point you should note when overridingEquals() is that your override shouldnever throw exceptions. Once again, this is because doing so could cause problems for dictionary classesand possibly certain other .NET base classes that internally call this method.
The static equals() Method
The static version of Equals() actually does the same thing as the virtual instance version. The difference
is that the static version takes two parameters and compares them for equality. This method is able to copewhen either of the objects isnull, and, therefore, provides an extra safeguard against throwing exceptionsif there is a risk that an object might benull. The static overload first checks whether the references it hasbeen passed arenull. If they are bothnull, it returnstrue (becausenull is considered to be equal tonull).If just one of them isnull, it returnsfalse. If both references actually refer to something, it calls thevirtual instance version ofEquals(). This means that when you override the instance version ofEquals(),the effect is as if you were overriding the static version as well.
operator overloading❘163
Comparison operator (==)
It is best to think of the comparison operator as an intermediate option between strict value comparison andstrict reference comparison. In most cases, writing the following means that you are comparing references:
bool b = (x == y); // x, y object references
However, it is accepted that there are some classes whose meanings are more intuitive if they are treatedas values. In those cases, it is better to override the comparison operator to perform a value comparison.Overriding operators is discussed next, but the obvious example of this is theSystem.String class
for which Microsoft has overridden this operator to compare the contents of the strings rather thantheir references.