если вы гуглите "ReferenceEquals string"
вы получите это
Ниже был принят ответ по ссылке, на случай, если ссылка умрет
В этом примере "obj1" и "obj2" - это отдельные экземпляры, верно?
Нет - строки являются ссылочными типами, а obj1 и obj2 - две переменные, указывающие на один и тот же экземпляр, частично из-за того, что называется интернированием; в принципе, любой строковый литерал в сборке * может иметь одну и ту же строковую ссылку. Это возможно только потому, что строки неизменны. Вы также можете проверить интернированные строки (string.IsInterned) и вручную интернировать, если хотите (string.Intern).
Когда две строки имеют одинаковое значение, они разделяют один и тот же экземпляр?
Они могут иметь один и тот же экземпляр; но это не гарантировано. Строки, которые генерируются на лету, обычно не интернируются; например, единственные, которые делятся ссылками здесь, это 2 & 4:
string tmp1 = "aa", tmp2 = "aaa";
строка s1 = новая строка ('a', 5),
s2 = "ааааа",
s3 = tmp1 + tmp2,
s4 = "ааааа";
Console.WriteLine (ReferenceEquals (s1, s2));
Console.WriteLine (ReferenceEquals (s1, s3));
Console.WriteLine (ReferenceEquals (s1, s4));
Console.WriteLine (ReferenceEquals (s2, s3));
Console.WriteLine (ReferenceEquals (s2, s4));
Console.WriteLine (ReferenceEquals (s3, s4));
* = строго: net-module