String s1 = "Hello";
String s2 = "Hello";
Здесь s1, s2 разные, но тогда почему ReferenceEquals() возвращает true
String s1 = "Hello";
String s2 = "Hello";
Здесь s1, s2 разные, но тогда почему ReferenceEquals() возвращает true
Это связано с интернированием - CLI автоматически повторно использует строки, полученные как литералы (т.е. строки, которые поступают непосредственно из исходного кода). Обратите внимание, что если вы сделали:
char[] chars = {'h','e','l','l','o'};
string s1 = new string(chars);
string s2 = new string(chars);
они бы не были тем же строковым экземпляром, что и не из литералов.
Это подтверждено документом Ldstr
IL:
Общая языковая инфраструктура (CLI) гарантирует, что результат двух команд ldstr, относящихся к двум токенам метаданных, которые имеют одну и ту же последовательность символов, возвращает точно тот же строковый объект (процесс, известный как "интернирование строк" ).
Строки неизменяемы, как только они создаются в памяти, следующей за теми же объектами String, ссылаются на ранее созданный объект String для большего http://msdn.microsoft.com/en-us/library/362314fe.aspx
Строка immutable
, поэтому использует ту же ссылку для одного значения
Также см. Eric lippert для всего этого
если вы 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
Вы также можете использовать статический метод String.Copy(String str)
для создания строк, которые будут разными объектами
String s1 = "Hello";
String s2 = string.Copy("Hello");
то s1 и s2 будут ссылаться на разные объекты.