The '==' operator for reference types is by default a reference
comparison. Only if the two values refer to the same object does it
return true, unless it has been overloaded. If '==' has been overloaded,
the version of '==' called is statically determined at compile time
based on the 'operator ==' definitions on the two types involved (one on
each side of the '==').
By default, '==' isn't defined for value types (structs), unless you
define one yourself.
The Equals method is virtual, and thus is selected by dynamic dispatch
at runtime. By default, it also performs a reference comparison, but it
may be overloaded. By the way, to ease the complications of checking for
null and avoiding calling Equals on a null reference, you can use
object.Equals(object,object) to call Equals and it can take care of
those details.
-- Barry