Работа со строками в .NET - Интернирование строк

ОГЛАВЛЕНИЕ

Интернирование строк

Говоря о строках, нельзя не упомянуть об интернированиистрок (тем более что эта тема обойдена вниманием в документации).

Если отбросить детали, механизм интернирования строк состоит в следующем:

    В рамках процесса (а не домена приложения) существует одна внутренняя хэш-таблица, ключами которой являются строки, а значениями – ссылки на них. Во время JIT-компиляции литеральные строки последовательно заносятся в таблицу (естественно, что одна литеральная строка встречается в таблице один раз).На этапе выполнения ссылки на литеральные строки присваиваются из этой таблицы.Можно поместить строку во внутреннюю таблицу во время выполнения с помощью метода String.Intern. Также можно проверить, содержится ли строка во внутренней таблице с помощью метода String.IsInterned.

А теперь посмотрим, к чему все это приводит. Проведем эксперимент – сравним две ссылки на строки с одинаковым значением. Метод стаким кодом:

string str = “literal string”;

return object.ReferenceEquals(str, “literalstring”);

 вернет true, потому что реально оба параметра ссылаются на один объект (из внутренней хэш-таблицы). Разумеется, если строку формировать динамически, то она не будет помещена во внутреннюю хэш-таблицу. Чтобы сделать это, нужно вызвать метод Intern:

string str = “literal”;

/*

* Следующая строчка кода создаст новую строку

* и присвоит ссылку на нее переменной str,

* а не изменит «старую» строку, на которую ссылается str.

*/

str += “ string”;

// без следующей строчки кода, метод вернул бы false

str = string.Intern(str);

return object.ReferenceEquals(str, “literalstring”);

 Нетрудно догадаться, что сравнение интернированных строк происходит значительно быстрее (только не стоит впадать в эйфорию, иинтернировать все, что можно – не забывайте о накладных расходах на вызовметода Intern).

Еще один интересный эффект описанного механизма – для передачи интернированных строк между доменами приложений в рамках одного процесса не нужен маршалинг содержимого строки – только ссылки (не забывайте,что внутренняя хэш-таблица одна на весь процесс).

Более подробно механизм интернирования строк описан в книгеДжеффри Рихтера «Программирование на платформе Microsoft .NET Framework».

Операции со строками

Иногда наступает момент, когда нам приходится работать с символами, составляющими строку. Изменить мы их, конечно, не можем, но затоможем узнать их количество (свойство Length), получитьсимвол по индексу (свойство-индексатор Chars) получитьмассив символов, содержащий всю строку, или ее часть (метод ToCharArray). Помимо этого, можно найти индекс символа в строке (методы IndexOf/LastIndexOf). Также есть возможность найти один символ изнекоторого набора (методы IndexOfAny/LastIndexOfAny).

Сравнение строк – тема полезная, но скучная. У типа String есть два статических метода – CompareOrdinalи Compare и экземплярный метод CompareTo,которые сравнивают строки. Метод CompareOrdinal делаетэто максимально быстро, поскольку просто сравнивает кодовые значения. Если же нужно учитывать регистр букв или региональные стандарты – используйте метод CompareTo, который всегда использует объект CultureInfoвызывающего потока или Compare, в который можнопередать объект CultureInfo отличный от Thread.CurrentCulture.

Подробнее об использовании типа Stringсм. в книге Джеффри Рихтера «Программирование на платформе Microsoft .NETFramework» и MSDN.

Многоязыковые приложения

Раз уж речь зашла о региональных стандартах, то нужно сказать и о реализации многоязыковых приложений (world-ready applications). Конечно, это тема отдельной статьи (или даже книги), поэтому я лишь немного расскажу об этом, оправдываясь тем, что есть раздел MSDN,посвященный данной теме.

Всегда есть шанс, что Ваше приложение может (или должно) использоваться не только в Вашей стране. Отсюда правило – литеральные строки,которые может увидеть пользователь (например, сообщения, о чем-то уведомляющие пользователя), должны храниться отдельно и подключаться к приложению в зависимостиот региональных настроек. В .NET есть механизмы,значительно упрощающие написание многоязыковых приложений (в том числе локализацию не только строк, но и форм).