== vs. Object.Equals(object) in .NET

string x = "hello";
string y = String.Copy(x);
string z = "hello";

To test if x points to the same object as y:

(object)x == (object)y  // false
x.ReferenceEquals(y)    // false
x.ReferenceEquals(z)    // true (because x and z are both constants they
                        //       will point to the same location in memory)

To test if x has the same string value as y:

x == y        // true
x == z        // true
x.Equals(y)   // true
y == "hello"  // true

Note that this is different to Java. In Java the == operator is not overloaded so a common mistake in Java is:

y == "hello"  // false (y is not the same object as "hello")

For string comparison in Java you need to always use .equals()

y.equals("hello")  // true

MSDN has clear and solid descriptions of both things.

object.Equals method

operator ==

Overloadable Operators

Guidelines for Overriding Equals() and Operator ==

Is this a good thing, what are the differences, and when/why should you use one over the other?

How can it be "good" or "bad" thing? One - method, another - operator. If reference equality is not sufficient, overload them, otherwise leave them as is. For primitive types they just work out of box.


Microsoft says that class implementers should make == behave as similarly as possible to Equals:

DO ensure that Object.Equals and the equality operators have exactly the same semantics

from http://msdn.microsoft.com/en-us/library/vstudio/7h9bszxx(v=vs.110).aspx


If you want to be certain you are getting IDENTITY comparison (when comparing references), then use ReferenceEquals instead.

If a class implementor does not override ==, then static method is looked for, at compile time, in base classes. If this search reaches Object, then Object.== is used. For classes, this is same as ReferenceEquals.

If class documentation is uncertain as to whether a given class (from a vendor other than Microsoft presumably) implements == as Equals or ReferenceEquals (or it could in theory be different than both of those), I sometimes avoid ==. Instead, I use the less readable Equals(a, b) or ReferenceEquals(a, b), depending on which meaning I want.

OTOH, ps2goat makes a good point that using == avoids exception if first operand is null (because == is a static operator). This is an argument in favor of using ==.


Removed controversial commentary regarding ==


UPDATE A recent Microsoft doc quote, from .Net 4.7.2 retrieved Feb. 2019, shows they still intend the two to behave similarly:

Object.Equals Method

Some languages such as C# and Visual Basic support operator overloading. When a type overloads the equality operator, it must also override the Equals(Object) method to provide the same functionality. This is typically accomplished by writing the Equals(Object) method in terms of the overloaded equality operator, as in the following example.


NOTE: See other answers for the consequences of == being a static method vs Equals being an instance method. I'm not claiming behavior is identical; I'm observing that Microsoft recommends making the two as similar as possible.

Tags:

.Net