Avatar ·

Как экранировать фигурные скобки в форматной строке .NET (C#)

Всем привет! Я только начал изучать C# и столкнулся с проблемой при форматировании строк.

Мне нужно вывести строку, содержащую фигурные скобки {}, например: "Значение равно {42}". Я использую метод String.Format или интерполяцию строк, но компилятор или среда выполнения считают, что фигурные скобки — это часть синтаксиса подстановки.

Вот пример кода, который не работает:

int number = 42;
string result = String.Format("Значение равно {number}"); // Ошибка: входная строка имела неверный формат
Console.WriteLine(result);

Или при интерполяции:

int number = 42;
string result = $"Значение равно {number}"; // Выводит "Значение равно 42", а мне нужно "Значение равно {42}"
Console.WriteLine(result);

Во втором случае C# подставляет значение переменной, а мне нужно, чтобы фигурные скобки остались как обычные символы. Как правильно экранировать фигурные скобки, чтобы они выводились как часть текста? Пробовал ставить обратный слеш перед ними — не помогает. Заранее спасибо за помощь!

<<>>

Экранирование фигурных скобок в форматных строках .NET

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

Рассмотрим два основных подхода:

1. Метод String.Format и составное форматирование

При использовании String.Format или методов, принимающих форматную строку (например, Console.WriteLine), экранирование работает так:

int number = 42;
string result = String.Format("Значение равно {{{0}}}", number);
Console.WriteLine(result); // Вывод: Значение равно {42}

Разберём строку "Значение равно {{{0}}}":

  • {{ — экранированная открывающая скобка (выводится как {)
  • {0} — место подстановки для первого аргумента (number)
  • }} — экранированная закрывающая скобка (выводится как })

Важно: количество скобок должно быть чётным, иначе возникнет исключение FormatException.

2. Интерполяция строк ($"...")

В интерполированных строках действует то же правило — удвоение скобок:

int number = 42;
string result = $"Значение равно {{{number}}}";
Console.WriteLine(result); // Вывод: Значение равно {42}

Здесь {{ и }} экранируют скобки, а {number} подставляет значение переменной.

3. Если нужно вывести скобки без подстановки

Если вам не нужно подставлять значения, а просто вывести текст с фигурными скобками:

string result = "Значение равно {{42}}"; // Ошибка! Так нельзя

В обычной строке (не форматной) экранирование не требуется:

string result = "Значение равно {42}"; // Правильно: выведет "Значение равно {42}"
Console.WriteLine(result);

Проблема возникает только в форматных строках — тех, которые передаются в String.Format, Console.WriteLine, StringBuilder.AppendFormat и т.д., а также в интерполированных строках ($"...").

Практические рекомендации

  • Для каждой фигурной скобки, которую нужно вывести, пишите две: {{ или }}.
  • Если вам нужно вывести скобку рядом с подстановкой, комбинируйте: $"{{{value}}}" — три скобки: две для экранирования, одна для подстановки.
  • Используйте string.Replace для динамического экранирования, если строка формируется программно.

Пример с динамическим экранированием:

string template = "Значение равно {0}";
string escaped = template.Replace("{", "{{").Replace("}", "}}");
// Но будьте осторожны: это заменит все скобки, включая плейсхолдеры!
// Лучше экранировать только нужные части.

Запомните простое правило: одна скобка — для форматирования, две скобки — для вывода. Это работает во всех версиях .NET Framework и .NET Core/.NET 5+.

<<>>

Альтернативный подход: использование StringBuilder.AppendFormat

Если вы работаете с StringBuilder и методом AppendFormat, экранирование работает точно так же — через удвоение скобок. Однако есть ещё один способ: можно вообще отказаться от форматной строки и использовать конкатенацию или интерполяцию с явным разделением.

Пример с StringBuilder

var sb = new System.Text.StringBuilder();
int number = 42;
sb.Append("Значение равно {");
sb.Append(number);
sb.Append("}");
Console.WriteLine(sb.ToString()); // Вывод: Значение равно {42}

Этот метод проще для понимания, но менее эффективен при большом количестве операций.

Использование StringBuilder.AppendFormat

var sb = new System.Text.StringBuilder();
sb.AppendFormat("Значение равно {{{0}}}", 42);
Console.WriteLine(sb.ToString()); // Вывод: Значение равно {42}

Когда это полезно

Метод без форматирования удобен, если:

  • Вы хотите избежать путаницы с экранированием.
  • Строка строится динамически из разных частей.
  • Вы новичок и конкатенация кажется более интуитивной.

Однако помните, что для производительности и читаемости кода лучше освоить правильное экранирование, так как String.Format и интерполяция строк — более современные и быстрые подходы.