Так как строки неизменяемы, переменные с одинаковыми строковыми значениями указывают на один и тот же строковый объект?

а)

        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.