Метод String.Intern просто добавляет ссылку на строку во внутренний пул или создает копию строки?

Предположим, у меня есть строка 'str'. Я хочу интернировать его с помощью метода String.Intern. Мне просто интересно, как именно работает String.Intern в случае, когда значение 'str' еще не интернировано. Описание метода из документации выглядит следующим образом:

Метод Intern использует внутренний пул для поиска строки, равной значению str. Если такая строка существует, возвращается ее ссылка во внутреннем пуле. Если строка не существует, ссылка на строку добавляется во внутренний пул, а затем эта ссылка возвращается.

Но этот отрывок из книги CLR через C# говорит о другом:

Стажер берет строку, получает для нее хэш-код и проверяет внутреннюю хеш-таблицу на соответствие. Если идентичная строка уже существует, возвращается ссылка на уже существующий объект String. Если идентичной строки не существует, создается копия строки, эта копия добавляется во внутреннюю хеш-таблицу и возвращается ссылка на эту копию.

Я предполагаю, что описание из документации является правильным. Итак, во внутренний пул добавляется только ссылка на str без копирования строкового объекта?


person ilya    schedule 28.02.2021    source источник


Ответы (1)


Это достаточно легко проверить напрямую:

// Make string from char[] to ensure it's not already interned
string s1 = new string(new[] { 'H', 'e', 'l', 'l', 'o' });
string i1 = string.Intern(s1);
bool result1 = object.ReferenceEquals(s1, i1);

string s2 = new string(new[] { 'H', 'e', 'l', 'l', 'o' });
string i2 = string.Intern(s2);
bool result2 = object.ReferenceEquals(s2, i2);

Обратите внимание, что result1 установлено на true, показывая, что исходный объект string не копируется. С другой стороны, result2 устанавливается в false, показывая, что второй сконструированный string объект "Hello" был найден во внутреннем пуле, и поэтому метод string.Intern() возвращает этот интернированный экземпляр вместо переданного вновь сконструированного экземпляра.

Метод string.Intern() не копирует строки. Он просто проверяет, равна ли переданная ссылка строке, уже находящейся в пуле, и добавляет ее в пул, если это не так.

person Peter Duniho    schedule 28.02.2021