Почему ReferenceEquals (s1, s2) возвращает true

  String s1 = "Hello";
  String s2 = "Hello";

Здесь s1, s2 разные, но тогда почему ReferenceEquals() возвращает true

Ответы

Ответ 1

Это связано с интернированием - CLI автоматически повторно использует строки, полученные как литералы (т.е. строки, которые поступают непосредственно из исходного кода). Обратите внимание, что если вы сделали:

char[] chars = {'h','e','l','l','o'};
string s1 = new string(chars);
string s2 = new string(chars);

они бы не были тем же строковым экземпляром, что и не из литералов.

Это подтверждено документом Ldstr IL:

Общая языковая инфраструктура (CLI) гарантирует, что результат двух команд ldstr, относящихся к двум токенам метаданных, которые имеют одну и ту же последовательность символов, возвращает точно тот же строковый объект (процесс, известный как "интернирование строк" ).

Ответ 2

Строки неизменяемы, как только они создаются в памяти, следующей за теми же объектами String, ссылаются на ранее созданный объект String для большего http://msdn.microsoft.com/en-us/library/362314fe.aspx

Ответ 3

Строка immutable, поэтому использует ту же ссылку для одного значения Также см. Eric lippert для всего этого

Ответ 4

если вы google "ReferenceEquals string"

вы получите this

Ниже был принят ответ по ссылке, если ссылка умирает

В этом примере "obj1" и "obj2" являются отдельными экземплярами, Right?

Нет - строки являются ссылочными типами, а obj1 и obj2 - две переменные, указывающие на один и тот же экземпляр, частично из-за чего-то называемого интернирования; в принципе, любой строковый литерал в сборке * может использовать одну и ту же строковую ссылку. Это возможно только потому, что строки неизменяемы. Вы также можете проверить интернированные строки (string.IsInterned) и вручную ставить, если хотите (string.Intern).

Когда две строки имеют одинаковое значение, они используют один и тот же экземпляр?

У них может быть один и тот же экземпляр; но это не гарантировано. Строки, которые были созданы "на лету", обычно не будут интернированы; например, единственные, которые используют ссылки здесь, - это 2 и 4:

строка tmp1 = "aa", tmp2 = "aaa";

string s1 = новая строка ('a', 5),

s2 = "aaaaa",

s3 = tmp1 + tmp2,

s4 = "aaaaa";

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

Ответ 5

Вы также можете использовать статический метод String.Copy(String str) для создания строк, которые будут разными объектами

String s1 = "Hello";
String s2 = string.Copy("Hello");

то s1 и s2 будут ссылаться на разные объекты.