Обзор вопросов по языка програмиированию C# и технологии NET
StringBuilder
SecureString
string
— это ссылочный тип (class
), а не struct
.string
является неизменяемым (immutable). После создания содержимое изменить нельзя.+=
, Replace
, Substring
, Insert
) создаётся новый объект в памяти, а старая строка остаётся в куче до тех пор, пока её не соберёт GC.Это значит:
string a = "Hello";
a += " World";
После этой операции в памяти будет 2 строки: "Hello"
и "Hello World"
.
⚠️ Поэтому частая конкатенация строк через +
в цикле — дорогая операция. Для таких задач используют StringBuilder
.
"Hello"
) автоматически сохраняются в String Intern Pool.Если ты дважды напишешь "Hello"
, то это будет одна и та же ссылка:
string a = "Hello";
string b = "Hello";
Console.WriteLine(object.ReferenceEquals(a, b)); // True
new string(...)
, она не будет в пуле, пока явно не вызвать string.Intern()
.string
переопределяет Equals()
и оператор ==
, поэтому сравнение идёт по значению, а не по ссылке:
string a = "test";
string b = "test";
Console.WriteLine(a == b); // True
==
сравнивает ссылки, но у string
это поведение изменено.Есть разные режимы сравнения:
Ordinal
(побайтовое сравнение),OrdinalIgnoreCase
(без учёта регистра),CurrentCulture
/ InvariantCulture
(с учётом культуры).string
может быть null
, " "
(пробелы), или ""
(пустая строка) — это разные состояния.Для удобства есть статические методы:
string.IsNullOrEmpty(str)
string.IsNullOrWhiteSpace(str)
StringBuilder
.Equals
, Compare
, указание культуры).==
может вернуть true
даже для разных объектов, если они литералы.null
-строке упадёт. Лучше использовать string.IsNullOrEmpty
.string
реализует интерфейсы: IComparable
, IEnumerable<char>
.string
— это по сути массив char
под капотом, но char[]
и string
— разные типы (у массива можно менять элементы, у строки — нет).char
= 2 байта).StringBuilder
внутри работает с буфером char[]
, чтобы не создавать новые объекты при изменениях.📌 Короткий ответ для джуна на собесе:
string
— это ссылочный неизменяемый тип в .NET. Каждое изменение строки создаёт новый объект. Литералы интернируются в пуле, поэтому одинаковые строковые литералы указывают на одну и ту же ссылку. Для частых изменений используютStringBuilder
. Сравнение строк переопределено и идёт по значению, а не по ссылке.
StringBuilder
+=
создаёт кучу мусора в памяти.StringBuilder
.var sb = new StringBuilder();
for (int i = 0; i < 1000; i++) sb.Append(i);
string result = sb.ToString();
Есть разные способы сравнивать строки:
StringComparison.Ordinal
→ по байтам (быстро, культура не учитывается).StringComparison.CurrentCulture
→ учитывает правила текущей культуры (напр. “i” и “İ”).StringComparison.InvariantCulture
→ инвариантный вариант для одинаковых результатов.Console.WriteLine("straße".Equals("STRASSE", StringComparison.OrdinalIgnoreCase)); // False
Console.WriteLine("straße".Equals("STRASSE", StringComparison.InvariantCultureIgnoreCase)); // True
SecureString
SecureString
, который позволял хранить зашифрованный буфер.Окей, разбор типа string
в .NET максимально подробно 🚀
Частая конкатенация строк через +
неэффективна.
Лучше использовать:
StringBuilder
для множественных изменений.string.Join
или интерполяцию.Для огромных строк — есть Span/Memory API в .NET Core.
Contains
, StartsWith
, EndsWith
IndexOf
, LastIndexOf
Substring
, Split
, Replace
Trim
, PadLeft
, PadRight
ToUpper
, ToLower
Но это же делает их опасными для хранения секретов (паролей, токенов):
SecureString
или Span<char>
.✨Dvurechensky✨