Почему 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 будут ссылаться на разные объекты.