Работа со строками в .NET

ОГЛАВЛЕНИЕ

Можно, конечно, долго и красиво говорить о сфере применения строк при написании приложений. Но зачем объяснять очевидное? Перейдем к делу. .NET Framework предоставляет немало типов для работы со строками, но в этой главе пойдет речь о тех из них, которые чаще используются на практике.

Неизменяемые строки

Важнейшим из типов для работы со строками для нас является System.String. Это элементарный ссылочный тип, который представляет собой неизменяемую последовательность Unicode-символов.

Элементарность типа System.String означает, конечно же, не простоту его реализации, а упрощенный синтаксис для работы с ним (в том числе, использование литеральных строкв коде). То, что String является ссылочным типом (reference type),говорит о том, что память для строк выделяется в управляемой куче, а не в стеке.

Безусловно, основным отличием типа Stringот его аналогов вне .NET Framework (например, CString в MFC) является его неизменяемость. Это значит, что нельзя изменить строку (ни добавить, ни удалить, ни изменить символы). Любые методы String, манипулирующие его содержимым (кпримеру, ToUpper) не изменяют содержимое текущейстроки, а возвращают новую строку. Есть только один способ изменить строку – использовать небезопасный (unsafe) код, но практической выгоды от этого никакой, поскольку такие строки могут некорректно сравниваться.

Неизменяемость строк, при первом знакомстве, кажется неудобной, но, во-первых, есть тип StringBuilder (о нем речь пойдет ниже), а во-вторых, у неизменяемых строк есть свои преимущества:

если строки идентичны, две строковые ссылки могут указывать на один объект, что позволяет более экономно использовать память и быстрее сравнивать строки – этот механизм называется интернированием строк.

не нужно синхронизировать потоки при работе со строкамиможно выполнить последовательность операций со строкой, не изменяя ее: if (str.TrimStart().ToUpper().StartsWith(“SELECT”))…

При этом нужно отметить, что хотя в примере создается два промежуточных объекта, на них нет ссылок в коде, и поэтому их память освободится при очередной сборке мусора.

Нужно отметить еще одну отличительную особенность типа String – он весьма тесно интегрирован с CLR(историческая справка – даже в ассемблере есть специальные команды для операций над строками). Это, разумеется, повышает эффективность работы со строками.Именно неизменяемостью и тесной интеграцией с CLRобъясняется то, что класс String – изолированный (sealed). В противном случае, написав производный класс, мымогли бы нарушить связь CLR и String.