Difference between == operator and Equals() method in C#?

There are several things going on. Firstly, in this example:

string s1 = "a";
string s2 = "a";
Console.WriteLine(s1 == s2);

You claim that:

Both are different object reference.

That’s not true due to string interning. s1 and s2 are references to the same object. The C# specification guarantees that – from section 2.4.4.5 of the C# 4 specification:

When two or more string literals that are equivalent according to the string equality operator (ยง7.10.7) appear in the same program, these string literals refer to the same string instance.

So in this particular case, you would still get “true” even if you printed object.ReferenceEquals(s1, s2), or if you made it use a true reference identity comparison with ==:

object s1 = "a";
object s2 = "a";
Console.WriteLine(s1 == s2); // Still prints True due to string literal interning

However, even if these were references to separate objects, == is overloaded for string. Overloading is a compile-time decision – the implementation to use depends on the compile-time types of the operands. So for example:

string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a == b); // Uses string's implementation, prints True

object c = a;
object d = b;
Console.WriteLine(c == d); // Reference identity comparison, prints False

Compare that with object.Equals(object) which is a virtual method. As it happens, String overloads this method as well, but importantly it overrides it. So if we change our code to:

string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a.Equals((object) b));

object c = a;
object d = b;
Console.WriteLine(c.Equals(d));

… then both method calls in the compiled code will simply be to object.Equals(object), but they’ll still both print True because of polymorphism: the implementation in String will be used.

Here’s what a call to the overloaded method would look like:

string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a.Equals(b)); // Calls string.Equals(string)

Leave a Comment