I have these statements and their\' results are near them.
string a = \"abc\";
string b = \"abc\";
Console.Writeline(a == b); //true
object x = a;
object y
string a = "abc";
string b = "abc";
Console.Writeline(a == b); //true
String references are the same for the same string due to String Interning
object x = a;
object y = b;
Console.Writeline(x == y); // true
Because the references are the same, two objects created from the same reference are also the same.
string c = new string(new char[] {'a','b','c'});
string d = new string(new char[] {'a','b','c'});
Here you create two NEW arrays of characters, these references are different.
Console.Writeline(c == d); // true
Strings have overloaded == to compare by value.
object k = c;
object m = d;
Since the previous references are different, these objects are different.
Console.Writeline(k.Equals(m)) //true
.Equals
uses the overloaded String equals
method, which again compare by value
Console.Writeline(k == m); // false
Here we check to see if the two references are the same... they are not
The key is figuring out when an equality is comparing references or values.
Objects, unless otherwise overloaded, compare references.
Structs, unless otherwise overloaded, compare values.
The ==
operator compares references (the memory addresses) while .Equals compares the actual object values. In the case of string, you get lucky and two identical strings can refer to the same address frequently. One of the joys of managed languages.
string c = new string(new char[] {'a','b','c'});
string d = new string(new char[] {'a','b','c'});
Console.WriteLine(c == d); // true
object k = c;
object m = d;
Console.WriteLine(k.Equals(m)); //true
Console.WriteLine(k == m); // false
Generates IL code, like this:
IL_0001: ldc.i4.3
IL_0002: newarr System.Char
IL_0007: dup
IL_0008: ldtoken <PrivateImplementationDetails>{61BB33F4-0CA5-4733-B259-764124AD1A79}.$$method0x6000002-1
IL_000D: call System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray
IL_0012: newobj System.String..ctor
IL_0017: stloc.0
IL_0018: ldc.i4.3
IL_0019: newarr System.Char
IL_001E: dup
IL_001F: ldtoken <PrivateImplementationDetails>{61BB33F4-0CA5-4733-B259-764124AD1A79}.$$method0x6000002-2
IL_0024: call System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray
IL_0029: newobj System.String..ctor
IL_002E: stloc.1
IL_002F: ldloc.0
IL_0030: ldloc.1
IL_0031: call System.String.op_Equality //STRING EQUALITY
IL_0036: call System.Console.WriteLine
IL_003B: nop
IL_003C: ldloc.0
IL_003D: stloc.2
IL_003E: ldloc.1
IL_003F: stloc.3
IL_0040: ldloc.2
IL_0041: ldloc.3
IL_0042: callvirt System.Object.Equals
IL_0047: call System.Console.WriteLine
IL_004C: nop
IL_004D: ldloc.2
IL_004E: ldloc.3
IL_004F: ceq //CEQ INSTRUCTION: **VALUES** EQUALITY !
IL_0051: call System.Console.WriteLine
As you can see the last instruction call CEQ instruction that makes comparison of values equality pushed on stack. The values pushed on stack are references of both boxed string, which are not equal.