Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое String в C#
Определение
String — это встроенный тип данных в C#, который представляет последовательность символов Unicode. Это один из самых часто используемых типов в .NET Framework.
String является **ссылочным типом** (reference type), хотя ведёт себя как **значимый тип** благодаря специальной обработке в .NET.
Основные характеристики
1. Неизменяемость (Immutability)
Строки в C# — это неизменяемые объекты. Это значит, что после создания строку нельзя изменить. Любая операция, которая кажется изменением строки, на самом деле создаёт новую строку.
string text = "Hello";
text = text + " World"; // Создаёт НОВУЮ строку "Hello World"
// Старая строка "Hello" остаётся в памяти
string str = "ABC";
str = str.ToLower(); // Создаёт новую строку "abc"
// Старая строка "ABC" остаётся в памяти
Почему это важно?
- Экономия памяти (строки могут быть оптимизированы)
- Потокобезопасность (можно передавать между потоками без блокировок)
- Кэширование (одинаковые строки могут ссылаться на один объект)
2. Ссылочный тип, но ведёт себя как значимый
string a = "Hello";
string b = a;
a = "World";
Console.WriteLine(a); // "World"
Console.WriteLine(b); // "Hello" — b не изменился!
// Это не то, что в обычных ссылочных типах:
List<int> list1 = new List<int> { 1, 2, 3 };
List<int> list2 = list1;
list1.Add(4);
Console.WriteLine(list2.Count); // 4 — обе переменные указывают на ОДИН объект
3. Каждая строка в коде — это объект
// Каждая из этих строк — отдельный объект в памяти
string s1 = "Hello"; // Объект 1
string s2 = "World"; // Объект 2
string s3 = "Hello"; // Может быть тот же объект 1 (интернирование)
string s4 = s1 + " " + s2; // Новый объект 3
Console.WriteLine(ReferenceEquals(s1, s3)); // true (интернирование строк)
Декларация и инициализация
// Различные способы создания строк
string str1 = "Hello"; // Литерал
string str2 = new string('a', 5); // "aaaaa" — повтор символа
string str3 = String.Empty; // Пустая строка ""
string str4 = null; // Null-строка
string str5 = $"Hello {name}"; // Интерполяция (С# 6.0+)
string str6 = "Line1\nLine2"; // Экранирование символов
string str7 = @"C:\Users\Name\file.txt"; // Verbatim string (буквальная)
string str8 = """
Multiline string (C# 11+)
Сохраняет форматирование
""";
Основные операции
Конкатенация
// Способ 1: + оператор (неэффективно для множественных операций)
string result = "Hello" + " " + "World";
// Способ 2: string.Concat (читаемый)
string result = string.Concat("Hello", " ", "World");
// Способ 3: StringBuilder (ПРАВИЛЬНЫЙ для циклов)
var sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
sb.Append("Line");
}
string result = sb.ToString(); // Создаёт одну строку
Сравнение
string a = "Hello";
string b = "hello";
// Чувствительно к регистру (по умолчанию)
Console.WriteLine(a == b); // false
Console.WriteLine(a.Equals(b)); // false
// Без учёта регистра
Console.WriteLine(a.Equals(b, StringComparison.OrdinalIgnoreCase)); // true
Console.WriteLine(string.Equals(a, b, StringComparison.OrdinalIgnoreCase)); // true
// Нулевые строки
string nullStr = null;
Console.WriteLine(string.IsNullOrEmpty(nullStr)); // true
Основные методы
string text = "Hello World";
// Длина
int length = text.Length; // 11
// Индексирование
char firstChar = text[0]; // 'H'
// Подстроки
string sub = text.Substring(0, 5); // "Hello"
string sub2 = text[0..5]; // "Hello" (С# 8.0+)
// Поиск
int index = text.IndexOf("World"); // 6
bool contains = text.Contains("World"); // true
// Замена
string replaced = text.Replace("World", "C#"); // "Hello C#"
// Разделение
string[] words = text.Split(' '); // ["Hello", "World"]
// Верхний/нижний регистр
string upper = text.ToUpper(); // "HELLO WORLD"
string lower = text.ToLower(); // "hello world"
// Удаление пробелов
string trimmed = text.Trim(); // Удалить с начала и конца
String vs StringBuilder
String — для простых операций (1-2 конкатенации):
string greeting = "Hello" + " " + userName; // OK
StringBuilder — для циклов и множественных операций:
// ❌ НЕПРАВИЛЬНО: создаёт 10000 новых строк
string result = "";
for (int i = 0; i < 10000; i++)
{
result += "Line" + i + "\n"; // Очень медленно!
}
// ✅ ПРАВИЛЬНО: создаёт одну строку
var sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
sb.Append("Line").Append(i).Append("\n");
}
string result = sb.ToString();
String интернирование
.NET оптимизирует память, храня строки в "пуле интернирования". Одинаковые строки могут ссылаться на один объект:
string a = "Hello";
string b = "Hello";
Console.WriteLine(ReferenceEquals(a, b)); // true — один объект!
// Но это не гарантировано:
string c = new string(new[] { 'H', 'e', 'l', 'l', 'o' });
Console.WriteLine(ReferenceEquals(a, c)); // false — разные объекты
// Для явного интернирования:
string d = string.Intern(c);
Console.WriteLine(ReferenceEquals(a, d)); // true
Null и Empty
string nullStr = null;
string empty = "";
string whitespace = " ";
// Проверка на null и пусто
string.IsNullOrEmpty(nullStr); // true
string.IsNullOrEmpty(empty); // true
string.IsNullOrEmpty(whitespace); // false (только пробелы)
// С# 6.0: null-conditional
string? optionalStr = null;
int? length = optionalStr?.Length; // null
// С# 8.0: nullable reference types
string? nullable = null; // Это ок
string notNullable = ""; // Не может быть null
Практические советы для интервью
- String — неизменяемый — это ключевой момент
- Для множественных операций — используй StringBuilder
- Сравнивай с правильным StringComparison — не только
== - Проверяй null перед использованием —
string.IsNullOrEmpty() - Интерполяция $ — современный способ — вместо
string.Format()
Золотое правило: String неизменяем, потокобезопасен и оптимизирован. Для работы с большими объёмами текста используй StringBuilder.