Coder Perfect

Are string.Equals() and == operator really same? [duplicate]


Are they identical? I ran into this issue today. The dump from the Immediate Window is as follows:

?s == tvi.Header 
?s == tvi.Header.ToString() 

As a result, both s and tvi. The word “Category” appears in the header, yet == returns false and Equals() returns true.

tvi defines s as string. The header is a WPF TreeViewItem. Header. So, what’s the deal with the diverse outcomes? In C#, I’ve always assumed they were interchangeable.

Can anybody explain why this is?

Asked by miliu

Solution #1

Two differences:

It’s worth noting that the latter isn’t a problem if you use object. Equals:

if (object.Equals(x, y)) // Fine even if x or y is null

Answered by Jon Skeet

Solution #2

The seeming conflicts in the question are generated by the Equals function being called on a string object in one case and the == operator being called on the System in the other. The object type implements equality in a different way than the string type (value vs. reference respectively).

Aside from that, any type can define == and Equals differently, therefore they are not interchangeable in general.

Here’s an example of double (from Joseph Albahari’s remark to C# language specification section 7.9.2):

double x = double.NaN;
Console.WriteLine (x == x);         // False
Console.WriteLine (x != x);         // True
Console.WriteLine (x.Equals(x));    // True

He continues by saying that the double. The Equals(double) method was created with lists and dictionaries in mind. The == operator, on the other hand, was created to adhere to the IEEE 754 floating point type standard.

In the instance of determining string equality, the industry standard is to avoid using both == and string. Most of the time, equals(string) is used. These methods check to see if two strings are identical character by character, which is rarely the case. It’s preferable to use string. Equals(string, StringComparison) allows you to specify the type of comparison you want to make. You can avoid a number of potential (and difficult-to-diagnose) issues by using the correct comparison.

Here’s one example:

string one = "Caf\u00e9";        // U+00E9 LATIN SMALL LETTER E WITH ACUTE
string two = "Cafe\u0301";       // U+0301 COMBINING ACUTE ACCENT
Console.WriteLine(one == two);                                          // False
Console.WriteLine(one.Equals(two));                                     // False
Console.WriteLine(one.Equals(two, StringComparison.InvariantCulture));  // True

If utilizing a nave (ordinal) equality, both strings in this example look the same (“Café”), making debugging difficult.

Answered by Jeffrey L Whitledge

Solution #3

Equals and ReferenceEquals are two “equals” concepts in C#. The == operator employs one or the other (or both) for most classes, and normally only tests for ReferenceEquals when dealing with reference types (though the string Class is an exception since C# already understands how to test for value equality).

Example Code:

var s1 = new StringBuilder("str");
var s2 = new StringBuilder("str");
StringBuilder sNull = null;

s1.Equals(s2); // True
object.ReferenceEquals(s1, s2); // False
s1 == s2 // True - it calls Equals within operator overload
s1 == sNull // False
object.ReferenceEquals(s1, sNull); // False
s1.Equals(sNull); // Nono!  Explode (Exception)

Answered by palswim

Solution #4

The TreeViewItem’s Header attribute is statically typed to be of type object.

As a result, the == returns false. This can be replicated using the following basic snippet:

object s1 = "Hallo";

// don't use a string literal to avoid interning
string s2 = new string(new char[] { 'H', 'a', 'l', 'l', 'o' });

bool equals = s1 == s2;         // equals is false
equals = string.Equals(s1, s2); // equals is true

Answered by Dirk Vollmar

Solution #5

In addition to Jon Skeet’s response, I’d like to clarify why you receive the result true most of the time when using == on distinct string instances with the same value:

string a = "Hell";
string b = "Hello";
a = a + "o";
Console.WriteLine(a == b);

Because strings are immutable, the runtime uses so-called string interning to allow both a and b to refer to the same string in memory. Because both a and b relate to the same instance, the result is true when using the == operator on objects. String interning is possible because each time you change one of them, a new string instance is created.

Jon Skeet’s response, by the way, is incomplete. True, x == y is false, but only because he’s comparing objects, which compare by reference. It will return true if you type (string)x == (string)y. As a result, the ==-operator on strings is overloaded, resulting in String. Underneath, equals

Answered by Daniel A.A. Pelsmaeker

Post is based on