Перейти к содержимому
Теория · Строки · урок 2 из 10

Интерполяция строк

Чек печатается по шаблону. В кассе заранее заготовлена строчка «Товар: ___, количество: ___», и при каждой покупке в пустые места подставляются название и число. Сам шаблон остаётся прежним, меняется только то, что в него вставили.

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

C#
string item = "Tea";
int qty = 2;
Console.WriteLine("Item: " + item + ", qty: " + qty); // Item: Tea, qty: 2
Console.WriteLine($"Item: {item}, qty: {qty}");       // Item: Tea, qty: 2

Обе инструкции печатают одно и то же. Разберём вторую:

  1. $ перед открывающей кавычкой говорит компилятору, что в строке есть места для значений.
  2. {item} — такое место: вместо него подставляется значение переменной item, то есть Tea.
  3. {qty} подставляет число 2, превращённое в текст.
  4. Всё остальное — обычный текст шаблона: Item: , запятая и пробелы.

Такой способ собирать строку называется интерполяцией строки, а строку с $ называют интерполированной. Шаблон читается так же, как будущий текст, поэтому в нём труднее ошибиться с пробелами.

Выражения в фигурных скобках

Здесь шаблон кассы и интерполяция расходятся. В пустые места чека вписывают готовые значения, а в фигурных скобках может стоять любое выражение: арифметика, сравнение, длина строки. C# вычисляет его и подставляет результат. Продолжим пример:

C#
int price = 35;
Console.WriteLine($"Total: {qty * price}");               // Total: 70
Console.WriteLine($"Letters: {item.Length}");             // Letters: 3
Console.WriteLine($"{qty} {(qty > 1 ? "cups" : "cup")}"); // 2 cups
Console.WriteLine($"Sum: {2 + 3}");                       // Sum: 5
Console.WriteLine($"{{qty}} = {qty}");                    // {qty} = 2

Давайте разберём строки по порядку:

  1. {qty * price} сначала умножает, а потом подставляет результат 70.
  2. {item.Length} подставляет длину строки "Tea".
  3. Условный оператор ?: берут в круглые скобки. Без них двоеточие внутри фигурных скобок C# прочитает как начало формата, о котором речь ниже, и программа не скомпилируется.
  4. {2 + 3} даёт Sum: 5. Помните "Sum: " + 2 + 3 из темы о типах? Там вышло Sum: 23, потому что плюс склеивал текст слева направо. В фигурных скобках выражение вычисляется отдельно, и 2 + 3 даёт число 5.
  5. Чтобы напечатать саму фигурную скобку, её удваивают: {{ и }}.

Ширина и формат

Чек печатают столбиками: названия слева, цены справа, и цифры стоят одна под другой. Для этого внутри фигурных скобок после значения указывают ширину и формат.

Ширина {x,5}

Число после запятой — ширина места в символах. Если значение короче, недостающие символы заполняются пробелами:

  • положительная ширина {x,5} прижимает значение к правому краю, и пробелы встают слева — так выравнивают числа;
  • отрицательная ширина {x,-8} прижимает значение к левому краю — так выравнивают названия.

Ширина задаёт минимум. Длинное значение не обрезается: {12345,3} печатает все пять цифр.

Формат {x:F2}

Буквы после двоеточия задают формат. F2 печатает ровно два знака дробной части и округляет лишние. Цифра после F — число знаков: F0 печатает без дробной части, F1 — с одним знаком. Для цен обычно берут F2.

Ширину и формат можно сочетать в одном месте: {total,8:F2}. Сначала пишут ширину, потом формат.

C#
decimal total = 4.5m;
Console.WriteLine($"|{"Tea",-8}|{70,5}|");     // |Tea     |   70|
Console.WriteLine($"|{"Coffee",-8}|{120,5}|"); // |Coffee  |  120|
Console.WriteLine($"{total:F2}");              // 4.50
Console.WriteLine($"{2.0 / 3:F2}");            // 0.67
Console.WriteLine($"[{total,8:F2}]");          // [    4.50]

Разберём, что получилось:

  1. В первых двух строках ширина -8 и 5 выстроила названия и цены в столбцы. Черты | показывают границы мест.
  2. {total:F2} дописало ноль: 4.5 превратилось в 4.50.
  3. {2.0 / 3:F2} округлило 0.666… до 0.67.
  4. {total,8:F2} сначала отформатировало число, а затем выровняло его по правому краю в восьми символах.

Комментарии показывают вывод на компьютере с английскими региональными настройками. С русскими настройками формат F2 ставит запятую: 4,50 и 0,67. Разделитель целой и дробной части в выводе берётся из настроек компьютера, а в коде всегда пишется точка.

Частая ошибка

Забыли знак $ перед строкой:

C#
string name = "Anna";
Console.WriteLine("Hi, {name}!"); // ✗
TEXT
warning CS0219: The variable 'name' is assigned but its value is never used

Программа компилируется и печатает Hi, {name}!. Без $ фигурные скобки — обычные символы, и имя переменной попадает в текст как есть. Компилятор выдаёт только предупреждение: переменная name нигде не используется. Это подсказка, что строка задумывалась интерполированной. Допишите $, и $"Hi, {name}!" напечатает Hi, Anna!.

Главное

  • В строке с $ вместо выражения в фигурных скобках подставляется его значение: $"qty: {qty}".
  • В фигурных скобках можно писать любое выражение, а условный оператор ?: берут в круглые скобки.
  • {x,5} задаёт ширину с выравниванием вправо, {x,-5} — влево, а {x:F2} печатает два знака дробной части.
  • Разделитель дробной части в выводе зависит от региональных настроек: 4.50 или 4,50.