Так как строки неизменяемы, переменные с одинаковыми строковыми значениями указывают на один и тот же строковый объект?
а)
string s = "value";
string s1 = "value";
Соответствующие переменные s и s1 указывают на тот же строковый объект (Im предполагает это из-за того, что строки неизменяемы)?
b) Я понимаю, что операторы равенства (==, > и т.д.) были переопределены для сравнения значений строковых объектов, но это то же самое верно при сравнении двух строк с использованием статических методов Object.Equals() и Object.ReferenceEquals()
спасибо
Ответы
Ответ 1
Нет, не все строки с одинаковым значением являются одной и той же ссылкой на объект.
Строки, сгенерированные компилятором, будут Interterned и будут одинаковыми. Строки, созданные во время выполнения, по умолчанию не интернированы и будут разными ссылками.
var s1 = "abc";
var s2 = "abc";
var s3 = String.Join("", new[] {"a", "b", "c"});
var s4 = string.Intern(s3);
Console.WriteLine(ReferenceEquals(s1, s2)); // Returns True
Console.WriteLine(ReferenceEquals(s1, s3)); // Returns False
Console.WriteLine(s1 == s3); // Returns True
Console.WriteLine(ReferenceEquals(s1, s4)); // Returns True
Обратите внимание на строку выше, где вы можете заставить строку быть интернированной с помощью String.Intern(string)
, которая затем позволяет использовать равенство объектов вместо равенства строк для некоторых проверок, что намного быстрее. Одним из примеров, когда это очень часто используется, является встроенный код XML-сериализатора вместе с таблицей имен.
Ответ 2
Да, они будут указывать на одну и ту же строку, потому что оба они определены как строковые литералы. Если вы создаете строку программно, вам придется вручную установить строку.
Это связано с тем, что .NET framework ставит строковые литералы в вашей программе в пул. Вы можете использовать String.Intern, чтобы получить эту ссылку, или вручную ставить свою собственную, созданную во время выполнения строку.
Подробнее см. docs для Intern:
Следовательно, экземпляр литерала с конкретным значением существует только один раз в системе.
Например, если вы назначаете одну и ту же литеральную строку нескольким переменным, среда выполнения возвращает ту же ссылку на литеральную строку из интервала пула и присваивает ее каждой переменной
Ответ 3
Если текущие CLR идентичные строки букв указывают на одни и те же фактические объекты. Процесс называется интернированием и применяется ко всем строкам времени компиляции.
Строки, созданные во время выполнения, не интернированы по умолчанию, но могут быть добавлены в интернированную коллекцию, вызывая string.Intern.
Пожалуйста, см. мой ответ на этот вопрос для подробного объяснения того, как хранятся строки .NET.