Хотя низкоуровневые детали языка CIL пока подробно не рассматривались, обратите внимание на многочисленные вызовы кода операции ldstr
("load string" — "загрузить строку"). Попросту говоря, код операции ldstr
языка CIL загружает новый объект string
в управляемую кучу. Предыдущий объект string
, который содержал значение "Му other string"
, будет со временем удален сборщиком мусора.
Так что же в точности из всего этого следует? Выражаясь кратко, класс string
может стать неэффективным и при неправильном употреблении приводить к "разбуханию" кода, особенно при выполнении конкатенации строк или при работе с большими объемами текстовых данных. Но если необходимо представлять элементарные символьные данные, такие как номер карточки социального страхования, имя и фамилия или простые фрагменты текста, используемые внутри приложения, тогда тип string
будет идеальным вариантом.
Однако когда строится приложение, в котором текстовые данные будут часто изменяться (подобное текстовому процессору), то представление обрабатываемых текстовых данных с применением объектов string
будет неудачным решением, т.к. оно практически наверняка (и часто косвенно) приведет к созданию излишних копий строковых данных. Тогда каким образом должен поступить программист? Ответ на этот вопрос вы найдете ниже.
Использование типа System.Text.StringBuilder
С учетом того, что тип string
может оказаться неэффективным при необдуманном использовании, библиотеки базовых классов .NET Core предоставляют пространство имен System.Text
. Внутри этого (относительно небольшого) пространства имен находится класс StringBuilder
. Как и System.String
, класс StringBuilder
определяет методы, которые позволяют, например, заменять или форматировать сегменты. Для применения класса StringBuilder
в файлах кода C# первым делом понадобится импортировать следующее пространство имен в файл кода (что в случае нового проекта Visual Studio уже должно быть сделано):
// Здесь определен класс StringBuilder:
using System.Text;
Уникальность класса StringBuilder
в том, что при вызове его членов производится прямое изменение внутренних символьных данных объекта (делая его более эффективным) без получения копии данных в модифицированном формате. При создании экземпляра StringBuilder
начальные значения объекта могут быть заданы через один из множества new
. Взгляните на следующий пример применения StringBuilder
:
static void FunWithStringBuilder
{
Console.WriteLine("=> Using the StringBuilder:");
StringBuilder sb = new StringBuilder("**** Fantastic Games ****");
sb.Append("\n");
sb.AppendLine("Half Life");
sb.AppendLine("Morrowind");
sb.AppendLine("Deus Ex" + "2");
sb.AppendLine("System Shock");
Console.WriteLine(sb.ToString);
sb.Replace("2", " Invisible War");
Console.WriteLine(sb.ToString);
Console.WriteLine("sb has {0} chars.", sb.Length);
Console.WriteLine;
}
Здесь создается объект StringBuilder
с начальным значением "**** Fantastic Games ****"
. Как видите, можно добавлять строки в конец внутреннего буфера, а также заменять или удалять любые символы. По умолчанию StringBuilder
способен хранить строку только длиной 16 символов или меньше (но при необходимости будет автоматически расширяться): однако стандартное начальное значение длины можно изменить посредством дополнительного аргумента конструктора:
// Создать экземпляр StringBuilder с исходным размером в 256 символов.
StringBuilder sb = new StringBuilder("**** Fantastic Games ****", 256);
При добавлении большего количества символов, чем в указанном лимите, объект StringBuilder
скопирует свои данные в новый экземпляр и увеличит размер буфера на заданный лимит.
Сужающие и расширяющие преобразования типов данных
Бьерн Страуструп , Бьёрн Страуструп , Валерий Федорович Альмухаметов , Ирина Сергеевна Козлова
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT