Язык программирования C#9 и платформа .NET5
Console.WriteLine();}В то время как приведенные здесь примеры просты и используют те же самые буквы в большинстве культур, если ваше приложение должно принимать во внимание разные наборы культур, тогда применение перечисления
становится обязательным.StringComparisonСтроки неизменяемы
Один из интересных аспектов класса
связан с тем, что после присваивания объекту string начального значения символьные данные не могут быть изменены. На первый взгляд это может показаться противоречащим действительности, ведь строкам постоянно присваиваются новые значения, а в классеSystem.Stringдоступен набор методов, которые, похоже, только то и делают, что изменяют символьные данные тем или иным образом (скажем, преобразуя их в верхний или нижний регистр). Тем не менее, присмотревшись внимательнее к тому, что происходит "за кулисами", вы заметите, что методы типаSystem.Stringна самом деле возвращают новый объектstringв модифицированном виде:stringstatic void StringsAreImmutable(){Console.WriteLine("=> Immutable Strings:\a");// Установить начальное значение для строки.string s1 = "This is my string.";Console.WriteLine("s1 = {0}", s1);// Преобразована ли строка si в верхний регистр?string upperString = s1.ToUpper();Console.WriteLine("upperString = {0}", upperString);// Нет! Строка si осталась в том же виде!Console.WriteLine("s1 = {0}", s1);}Просмотрев показанный далее вывод, можно убедиться, что в результате вызова метода
исходный объектToUpper()не преобразовывался в верхний регистр. Взамен была возвращена копия переменной типаstring(s1)в измененном формате.strings1 = This is my string.upperString = THIS IS MY STRING.s1 = This is my string.Тот же самый закон неизменяемости строк действует и в случае применения операции присваивания С#. Чтобы проиллюстрировать, реализуем следующий метод
:StringsAreImmutable2()static void StringsAreImmutable2(){Console.WriteLine("=> Immutable Strings 2:\a");string s2 = "My other string";s2 = "New string value";}Скомпилируйте приложение и запустите
(см. главу 1). Ниже приведен код CIL, который будет сгенерирован для методаildasm.exe:StringsAreImmutable2().method private hidebysig static void StringsAreImmutable2() cil managed{// Code size 21 (0x15).maxstack 1.locals init (string V_0)IL_0000: nopIL_0001: ldstr "My other string"IL_0006: stloc.0IL_0007: ldstr "New string value" /* 70000B3B */IL_000c: stloc.0IL_000d: ldloc.0IL_0013: nopIL_0014: ret} // end of method Program::StringsAreImmutable2Хотя низкоуровневые детали языка CIL пока подробно не рассматривались, обратите внимание на многочисленные вызовы кода операции
("load string" — "загрузить строку"). Попросту говоря, код операцииldstrязыка CIL загружает новый объектldstrв управляемую кучу. Предыдущий объектstring, который содержал значениеstring, будет со временем удален сборщиком мусора."Му other string"Так что же в точности из всего этого следует? Выражаясь кратко, класс
может стать неэффективным и при неправильном употреблении приводить к "разбуханию" кода, особенно при выполнении конкатенации строк или при работе с большими объемами текстовых данных. Но если необходимо представлять элементарные символьные данные, такие как номер карточки социального страхования, имя и фамилия или простые фрагменты текста, используемые внутри приложения, тогда типstringбудет идеальным вариантом.stringОднако когда строится приложение, в котором текстовые данные будут часто изменяться (подобное текстовому процессору), то представление обрабатываемых текстовых данных с применением объектов
будет неудачным решением, т.к. оно практически наверняка (и часто косвенно) приведет к созданию излишних копий строковых данных. Тогда каким образом должен поступить программист? Ответ на этот вопрос вы найдете ниже.stringИспользование типа System.Text.StringBuilder
С учетом того, что тип
может оказаться неэффективным при необдуманном использовании, библиотеки базовых классов .NET Core предоставляют пространство именstring. Внутри этого (относительно небольшого) пространства имен находится классSystem.Text. Как иStringBuilder, классSystem.Stringопределяет методы, которые позволяют, например, заменять или форматировать сегменты. Для применения классаStringBuilderв файлах кода C# первым делом понадобится импортировать следующее пространство имен в файл кода (что в случае нового проекта Visual Studio уже должно быть сделано):StringBuilder