OOP Course
Сьогодні

Підрозділ 11.3

Форматування та інтерполяція рядків

Пояснює форматування та інтерполяцію рядків: плейсхолдери, string.Format, специфікатори валюти, чисел, відсотків, настроювані формати, ToString і вирівнювання.

11.3. Форматування та інтерполяція рядків

Виведення числових, датових та складних рядкових значень вимагає контролю над форматом: кількість знаків після коми, вирівнювання колонок у звіті, символ валюти. C# надає три підходи до вставки значень у рядки, кожен зі своїми сценаріями застосування.

Форматування рядків у C# — три підходи та специфікатори

Конкатенація (+)

Найпростіший спосіб — об'єднання через +. Числові та інші типи автоматично перетворюються через ToString():

string name = "Петренко";
int    age  = 67;
double bp   = 140.5;

string s = "Пацієнт: " + name + ", вік: " + age + ", АТ: " + bp.ToString("F2") + " мм рт.ст.";

Недоліки: кожен + породжує новий об'єкт у heap; при більш ніж трьох значеннях код стає важкочитаним; числові специфікатори потрібно задавати через ToString() окремо, що розриває читабельний потік рядка. Конкатенація + доцільна лише для об'єднання двох-трьох частин без специфікаторів.

Важливий нюанс компілятора: якщо всі операнди є рядковими літералами ("a" + "b" + "c"), Roslyn розраховує результат ще під час компіляції і поміщає в IL єдиний рядок "abc" — жодної алокації під час виконання. Проте як тільки з'являється змінна або вираз — рядок будується динамічно.

string.Format()

Метод string.Format приймає рядок-шаблон із плейсхолдерами {0}, {1}, ... і набір аргументів:

string s = string.Format(
    "Пацієнт: {0}, вік: {1}, АТ: {2:F2} мм рт.ст.",
    name, age, bp);

Переваги string.Format:

  • Шаблон відокремлено від даних — зручно для локалізації (зберігати шаблони в ресурсних файлах).
  • Один аргумент можна повторити кілька разів: "{0}...{0}".
  • Плейсхолдер {index:specifier} поєднує позицію і формат в одному місці.

Метод string.Format (і клас StringBuilder.AppendFormat) також приймає необов'язковий перший параметр типу IFormatProvider — зазвичай CultureInfo. Він визначає культурно-залежне форматування: який символ використовується як десятковий роздільник, розділювач тисяч, символ валюти. За замовчуванням використовується культура поточного потоку (CultureInfo.CurrentCulture):

using System.Globalization;

double bp = 140.5;
// В українській культурі десятковий роздільник — кома
string ua = string.Format(CultureInfo.GetCultureInfo("uk-UA"), "{0:F2}", bp); // "140,50"
// В американській — крапка
string us = string.Format(CultureInfo.InvariantCulture, "{0:F2}", bp);        // "140.50"

Це критично важливо при записі числових даних у файли або передачі між сервісами: якщо на сервері культура uk-UA, а клієнт очікує InvariantCulture — парсинг поверне помилку. Для серіалізації даних завжди слід явно передавати CultureInfo.InvariantCulture.

Інтерполяція рядків ($"...")

Інтерполяція — найчитабельніший і найчастіше вживаний підхід. Рядок починається зі знака $; всередині фігурних дужок — будь-який вираз C#:

string s = $"Пацієнт: {name}, вік: {age}, АТ: {bp:F2} мм рт.ст.";

Компілятор перетворює $"..." у виклик string.Format() — тобто на рівні IL обидва підходи ідентичні. Переваги $"...": імена змінних замість номерів, компілятор перевіряє типи на етапі компіляції, будь-які вирази прямо у {}:

int systolic  = 140;
int diastolic = 90;
Console.WriteLine($"АТ: {systolic}/{diastolic}{(systolic > 130 ? "підвищений" : "норма")}");
// АТ: 140/90 — підвищений

Починаючи з C# 10, компілятор застосовує додаткову оптимізацію: замість виклику string.Format він використовує DefaultInterpolatedStringHandler — структуру, яка будує рядок через Span<char> на стеку без зайвих алокацій. Ця оптимізація вмикається автоматично і не потребує змін у коді.

Інтерполяцію можна поєднати з verbatim-рядком (@) для тексту з зворотними слешами або переносами рядків без \n:

// @$ або $@ — обидва порядки допустимі з C# 8
string path = $@"C:\Patients\{lastName}\record.txt";

Специфікатори форматування

Специфікатори використовуються однаково у string.Format та $"..." через двокрапку після виразу: {value:specifier}.

Числові специфікатори

Специфікатор Назва Приклад
C2 Валюта {23.7:C2}23,70 грн.
D4 Ціле (з нулями) {23:D4}0023
F2 Дробове {140.567:F2}140,57
N0 Тисячний роздільник {12345:N0}12 345
P1 Відсоток {0.153:P1}15,3%
E2 Науковий формат {12345.6:E2}1,23E+004

Число після літери специфікатора задає кількість знаків після коми (або мінімальну кількість цифр для D).

Детальніше про кожен:

  • C (Currency) — додає символ валюти поточної культури. Кількість знаків після коми визначається культурою за замовчуванням (зазвичай 2). Для медичного застосунку в Україні дасть або грн. залежно від версії .NET і культури ОС.

  • D (Decimal) — тільки для цілочисельних типів (int, long). Заповнює нулями зліва до мінімальної кількості цифр. {42:D6}"000042". Ідеальний для номерів медичних карток і ідентифікаторів пацієнтів.

  • F (Fixed-point) — дробове число з фіксованою кількістю знаків після коми. Використовується для медичних показників: артеріальний тиск, глюкоза, температура.

  • N (Number) — додає тисячний роздільник. {12345678:N0}"12 345 678". Зручний для сум у фінансових звітах лікарні.

  • P (Percent) — множить значення на 100 і додає знак %. Значення 0.847 дасть "84,7%". Корисний для статистики успішності лікування.

  • E (Exponential) — науковий запис. Використовується рідко — лише для дуже великих або малих чисел у лабораторних дослідженнях.

Довільний формат через

Символ # дозволяє задати довільний шаблон. Наприклад, телефон пацієнта:

long phone = 380671234567;
Console.WriteLine($"{phone:+## (###) ###-##-##}"); // +38 (067) 123-45-67

У шаблонах # означає «необов'язкова цифра» (нічого не виводиться якщо цифри немає), а 0 — «обов'язкова цифра» (виводиться 0). Шаблон обробляється справа наліво від десяткової крапки — тому цифри з кінця числа розподіляються по позиціях шаблону.

Вирівнювання

Після виразу і специфікатора можна вказати ширину поля через кому. Від'ємне значення — вирівнювання ліворуч, додатне — праворуч:

string name = "Петренко";
double value = 140.5;

Console.WriteLine($"|{"Ім'я",15}|{"АТ",8}|");
Console.WriteLine($"|{name,15}|{value,8:F1}|");
Console.WriteLine($"|{name,-15}|{value,-8:F1}|");

Вивід:

|           Ім'я|      АТ|
|        Петренко|   140,5|
|Петренко       |140,5   |

Механізм вирівнювання є надзвичайно зручним для побудови текстових таблиць: кожна колонка має фіксовану ширину, а значення автоматично вирівнюються. Правостороннє вирівнювання ({value,8}) стандартне для чисел; лівостороннє ({name,-20}) — для текстових полів.

Raw string literals (C# 11)

Починаючи з C# 11, рядки можна записувати у потрійних лапках """...""". Такий рядок може містити лапки та переноси рядків без екранування:

string template = """
    Виписка з лікарні
    Пацієнт: Петренко І.С.
    Діагноз: "Гіпертензія артеріальна"
    Рекомендації: прийом "Лізиноприл" 10 мг
    """;
Console.WriteLine(template);

Raw string literals особливо зручні для JSON-шаблонів, SQL-запитів або HTML-фрагментів у медичних застосунках. Відступ, що збігається з відступом закриваючих """, автоматично видаляється компілятором — рядок зберігатиме відносні відступи правильно.

Крім того, raw string literals можна поєднувати з $ для інтерполяції: $"""...""". Якщо всередині потрібна фігурна дужка як літерал, вона записується подвоєно: {{ і }}.

Метод ToString() зі специфікатором

Будь-який числовий тип підтримує ToString(specifier) — ті самі специфікатори, що й у Format:

double bp     = 140.567;
int    patId  = 42;
long   phone  = 380671234567;

Console.WriteLine(bp.ToString("F1"));               // 140,6
Console.WriteLine(patId.ToString("D6"));            // 000042
Console.WriteLine(phone.ToString("+## (###) ###-##-##")); // +38 (067) 123-45-67

ToString(specifier) також приймає другий параметр IFormatProvider: bp.ToString("F2", CultureInfo.InvariantCulture). Це той самий механізм, що й у string.Format — реалізується через інтерфейс IFormattable, який реалізований усіма числовими типами .NET.

Форматований звіт пацієнта — runnable приклад

Демонстрація специфікаторів C/F/N/P у клінічному звіті:

Таблиця відділення з вирівнюванням — runnable приклад

Форматована таблиця через вирівнювання у $"...":

Розроблено Tomka Yurii · © 2026 ·