Многострочные строки в C#: от хаков до C# 11 — полный гайд

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Однажды на Stack Overflow: Проклятие длинных строк в C#

Представьте ситуацию. Вы пишете на C# конфигурационный JSON, SQL-запрос или, скажем, HTML-шаблон прямо в коде. Строка получается длинной, некрасивой и абсолютно нечитаемой. Вы нажимаете Enter, чтобы перенести текст... и получаете ошибку компиляции. Знакомо?

Вопрос "Multiline string literal in C#" на Stack Overflow собрал десятки тысяч просмотров. И это не случайно. Долгое время C# был не самым дружелюбным языком для работы с многострочным текстом. Но времена меняются. В этой статье мы пройдем путь от костылей до элегантных решений, которые появились в C# 11.

Если вы пишете на C# и работаете с многострочными строковыми литералами, этот материал сэкономит вам часы гугления. Поехали!

Проблема: Почему просто нажать Enter — плохая идея?

В C# (как и в C++) строковый литерал — это последовательность символов, заключенная в кавычки. Перенос строки внутри таких кавычек — это синтаксическая ошибка. Компилятор просто не поймет, где заканчивается строка.

Вот как НЕ надо делать:

// Ошибка компиляции!
string query = "SELECT * FROM Users
WHERE Age > 18
ORDER BY Name";

Компилятор увидит "SELECT * FROM Users — и всё. Дальше идет мрак. Раньше разработчики выкручивались как могли. Давайте разберем эволюцию решений.

Старый способ: Verbatim string (@-строка) — палочка-выручалочка

Первое, что приходит на ум — это verbatim string literal. Вы просто ставите @ перед открывающей кавычкой. Это отключает интерпретацию escape-последовательностей (кроме двойных кавычек "").

Но есть нюанс: отступы тоже становятся частью строки.

Пример с verbatim string:

string json = @"{
    ""name"": ""Alice"",
    ""age"": 30
}";
Console.WriteLine(json);

Вывод:

{
    "name": "Alice",
    "age": 30
}

Плюсы:

  • Работает во всех версиях C#.
  • Не нужно экранировать обратную косую черту (\).

Минусы:

  • Кавычки внутри приходится удваивать ("") — это ужасно, если много JSON.
  • Отступы слева (пробелы/табуляции) попадают в итоговую строку.
  • Нельзя смешивать с интерполяцией строк ($) напрямую (но можно $@).

Этот метод до сих пор популярен, но для чистого кода он не идеален. Настоящий прорыв случился в C# 11.

Новейший способ: Raw string literal (C# 11 и .NET 7+)

Начиная с C# 11, у нас есть raw string literal — буквально "сырой строковый литерал". Он решает 99% проблем многострочности.

Синтаксис: три и более двойных кавычки подряд (""").

Пример 1: Простой JSON без экранирования

string json = """
    {
        "name": "Alice",
        "age": 30
    }
    """;
Console.WriteLine(json);

Вывод:

{
    "name": "Alice",
    "age": 30
}

Магия: Кавычки внутри строки не нужно удваивать! Компилятор понимает, что строка закончилась, только когда видит три кавычки подряд.

Пример 2: SQL-запрос с отступами

string query = """
    SELECT 
        u.Name,
        o.OrderDate
    FROM Users u
    JOIN Orders o ON u.Id = o.UserId
    WHERE o.Status = 'Active'
    ORDER BY o.OrderDate DESC
    """;
Console.WriteLine(query);

Важно про отступы: Закрывающие кавычки (""") задают базовый уровень отступа. Все строки, которые имеют отступ меньше, чем закрывающие кавычки, будут обрезаны. Это позволяет сохранить читаемость кода, не захламляя строку лишними пробелами.

Пример 3: Интерполяция в raw string

Да, вы можете смешивать raw string literals с интерполяцией. Для этого нужно поставить знак доллара и то количество кавычек, которое не конфликтует с фигурными скобками.

string name = "Bob";
int age = 25;

string message = $$"""
    Hello, {{name}}!
    You are {{age}} years old.
    """;
Console.WriteLine(message);

Вывод:

Hello, Bob!
You are 25 years old.

Если вы используете $$ и {{ }}, то одинарные фигурные скобки { } внутри строки воспринимаются как обычные символы.

Сравнение методов: от старины до современности

Давайте сведем всё в таблицу (мысленно, но наглядно).

МетодВерсия C#Экранирование кавычекОтступыИнтерполяция
string + "\n"ВсеНормальноеРучноеДа
@"" (Verbatim)ВсеУдвоение ""СохраняютсяЧерез $@
""" """ (Raw)C# 11+Не нужноАвто-удалениеЧерез $$

Вывод: Если ваш проект на .NET 7 или новее — используйте raw string literal. Это самый чистый и современный способ.

Когда старые методы еще имеют смысл?

Не спешите удалять @-строки из памяти. Есть сценарии, где они удобнее:

  • Короткие пути к файлам: @"C:\Users\Public\file.txt" — короче, чем """C:\Users\Public\file.txt""".
  • Старые проекты: Если вы застряли на .NET Framework 4.x, raw string literals вам недоступны.
  • Одиночные строки с кавычками

Блоги

Рекомендаций по книгам