2
string a = "abc";
string b = "abc";
Console.WriteLine(String.ReferenceEquals(a, b));

a and b are CLEARLY different references, yet, I get true. Why is this? Somewhere I've read that when you assign abc to b, the compiler sees that there's already the exact abc value in the heap and points to the same memory address as a, but if this was the case, then by that logic the last line of this code below should print true:

class SomeClass
{
    public int _num;
    public SomeClass(int num)
    {
        _num = num;
    }
}
var a = new SomeClass(3);
var b = new SomeClass(3);
Console.WriteLine(Object.ReferenceEquals(a, b)); // prints false
daremkd
  • 8,244
  • 6
  • 40
  • 66
  • 1
    Instances of `string` are interned. Instances of `SomeClass` are not. – Dennis_E Mar 11 '16 at 09:56
  • 1
    Have you see [this SO post](http://stackoverflow.com/questions/9112610/referenceequals-working-wrong-with-strings) &/or [this](http://stackoverflow.com/questions/4232789/why-does-referenceequalss1-s2-returns-true) ? – Michael Mar 11 '16 at 09:57

2 Answers2

1

In the compilation step, string literals are pooled and all references to a specific value will be equal.

From the specifications (boldface mine):

Each string literal does not necessarily result in a new string instance. When two or more string literals that are equivalent according to the string equality operator (Section 7.9.7) appear in the same assembly, these string literals refer to the same string instance.

Idos
  • 15,053
  • 14
  • 60
  • 75
1

a and b are CLEARLY different references.

No, they are not. That string is interned.

The 'catch' with strings in general is that == calls the string.Equals method, which does not only compare references, but also the actual representation of the string.

Proof:

string a = "a";
string b = "a"; // intering
string c = new string(a.ToCharArray()); // no interning

bool r;

r = a == b; // true: references the same
r = a == c; // true: references different, match string value

r = (object)a == (object)b; // true: references the same

r = (object)a == (object)c; // false: references different
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325