День сто двадцатый. #ВопросыНаСобеседовании

Самые часто задаваемые вопросы на собеседовании по C#

10. В чём разница между String и StringBuilder в C#?

Класс String из пространства имён System – это последовательная коллекция символов Unicode (объектов System.Char), представляющая собой текст. Объект String является неизменяемым. Максимальный размер объекта String в памяти составляет 2 ГБ (около 1 миллиарда символов).

Хотя строка является ссылочным типом, операторы равенства (== и !=) Определены для сравнения значений строковых объектов, а не ссылок. Однако после упаковки сравнение происходит на строковых экземплярах:

string a = "hello";  

string b = "h";

b += "ello"; // Добавляем к строке 'b'

Console.WriteLine(a==b); // true

Console.WriteLine((object)a == (object)b); // false

Последняя строка выдаёт false, поскольку после упаковки объектов сравниваются ссылки на экземпляры.



С другой стороны, StringBuilder (System.Text) представляет собой изменяемую строку символов. Этот класс не может быть унаследован. Емкость этого объекта по умолчанию составляет 16 символов, а максимальная емкость превышает 2 миллиарда символов.

StringBuilder sb = new StringBuilder();

sb.Append("Hello");

sb.Append("World");

Console.WriteLine(sb.ToString());



Как это работает

Компилятор создает новый строковый объект для каждой конкатенации строк для хранения новой последовательности символов (другими словами, существующей строки и новых данных), и этот новый объект возвращается обратно в переменную.

Например, если вы объединяете две строки, то конкатенация строк выделяет новую строку длины (str1.Length + str2.Length) и копирует первую и вторую строки в эту строку.

Это приводит к многократному повторному копированию строк, например объединение N строк (var result = str1 + str2 + str3 + ... + strN;) потребует N-1 выделения памяти и N-1 операций копирования. Это может стать очень дорогим для больших значений N.

С другой стороны, объект StringBuilder поддерживает буфер для размещения конкатенации новых данных. Новые данные добавляются в буфер, если доступно пространство; в противном случае выделяется новый больший буфер, данные из исходного буфера копируются в новый буфер, а новые данные добавляются в новый буфер.

Например, если вы объединяете 20 строк, StringBuilder просто добавляет одну за другой в свой буфер, а затем возвращает результат по запросу.



Когда что использовать

Не используйте строку, если вы не знаете количество конкатенаций или если количество конкатенаций большое:

string x = "";

for (int i = 0; i < 100000; i++)

{

x += "!";

}

Используйте класс String, если вы объединяете фиксированное число объектов String. В этом случае компилятор может даже объединить отдельные операции конкатенации в одну операцию, особенно в случае конкатенации строковых литералов:

string x = "Hello" + " " + "World";  

С другой стороны, не используйте StringBuilder для тривиальной конкатенации, поскольку выделение и инициализация StringBuilder занимает некоторое время, которое может оказаться бесполезным для небольшого числа конкатенаций:

StringBuilder sb = new StringBuilder();  

sb.Append("Hello");

sb.Append("World");

Console.WriteLine(sb.ToString());



Прочие Советы

1. StringBuilder может быть еще более эффективным при указании размера буфера в конструкторе, чтобы избежать излишних удвоений размера буфера, когда ему не хватает места.

2. Также, если у вас есть массив, который вы хотите объединить в строку, рассмотрите возможность явного вызова "String.Concat" или "String.Join", если вам нужен разделитель.



Источник: https://www.c-sharpcorner.com