Как экранировать фигурные скобки в форматной строке .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 и интерполяция строк — более современные и быстрые подходы.