Интерполяция строк
Чек печатается по шаблону. В кассе заранее заготовлена строчка «Товар: ___, количество: ___», и при каждой покупке в пустые места подставляются название и число. Сам шаблон остаётся прежним, меняется только то, что в него вставили.
До сих пор текст из значений собирали плюсом. Это работает, но кавычки и плюсы быстро перемешиваются, а пробел на границе куска нередко теряется. Сравните два способа собрать одну и ту же строку:
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Обе инструкции печатают одно и то же. Разберём вторую:
$перед открывающей кавычкой говорит компилятору, что в строке есть места для значений.{item}— такое место: вместо него подставляется значение переменнойitem, то естьTea.{qty}подставляет число2, превращённое в текст.- Всё остальное — обычный текст шаблона:
Item:, запятая и пробелы.
Такой способ собирать строку называется интерполяцией строки, а строку с $ называют интерполированной. Шаблон читается так же, как будущий текст, поэтому в нём труднее ошибиться с пробелами.
Выражения в фигурных скобках
Здесь шаблон кассы и интерполяция расходятся. В пустые места чека вписывают готовые значения, а в фигурных скобках может стоять любое выражение: арифметика, сравнение, длина строки. 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Давайте разберём строки по порядку:
{qty * price}сначала умножает, а потом подставляет результат70.{item.Length}подставляет длину строки"Tea".- Условный оператор
?:берут в круглые скобки. Без них двоеточие внутри фигурных скобок C# прочитает как начало формата, о котором речь ниже, и программа не скомпилируется. {2 + 3}даётSum: 5. Помните"Sum: " + 2 + 3из темы о типах? Там вышлоSum: 23, потому что плюс склеивал текст слева направо. В фигурных скобках выражение вычисляется отдельно, и2 + 3даёт число5.- Чтобы напечатать саму фигурную скобку, её удваивают:
{{и}}.
Ширина и формат
Чек печатают столбиками: названия слева, цены справа, и цифры стоят одна под другой. Для этого внутри фигурных скобок после значения указывают ширину и формат.
Ширина {x,5}
Число после запятой — ширина места в символах. Если значение короче, недостающие символы заполняются пробелами:
- положительная ширина
{x,5}прижимает значение к правому краю, и пробелы встают слева — так выравнивают числа; - отрицательная ширина
{x,-8}прижимает значение к левому краю — так выравнивают названия.
Ширина задаёт минимум. Длинное значение не обрезается: {12345,3} печатает все пять цифр.
Формат {x:F2}
Буквы после двоеточия задают формат. F2 печатает ровно два знака дробной части и округляет лишние. Цифра после F — число знаков: F0 печатает без дробной части, F1 — с одним знаком. Для цен обычно берут F2.
Ширину и формат можно сочетать в одном месте: {total,8:F2}. Сначала пишут ширину, потом формат.
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]Разберём, что получилось:
- В первых двух строках ширина
-8и5выстроила названия и цены в столбцы. Черты|показывают границы мест. {total:F2}дописало ноль:4.5превратилось в4.50.{2.0 / 3:F2}округлило0.666…до0.67.{total,8:F2}сначала отформатировало число, а затем выровняло его по правому краю в восьми символах.
Комментарии показывают вывод на компьютере с английскими региональными настройками. С русскими настройками формат F2 ставит запятую: 4,50 и 0,67. Разделитель целой и дробной части в выводе берётся из настроек компьютера, а в коде всегда пишется точка.
Частая ошибка
Забыли знак $ перед строкой:
string name = "Anna";
Console.WriteLine("Hi, {name}!"); // ✗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.