Chaves em C#: como escapar e o que há dentro

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: quando o código começa a "entortar"

\n\n

Imagine: você está escrevendo em C#, precisa exibir uma mensagem como Valor: {42}. Você usa String.Format("Valor: {0}", 42) — e obtém o resultado esperado. Agora tente exibir apenas {42} sem substituição. Ingenuamente escrevendo:

\n\n
string result = String.Format("{{42}}");
\n\n

Você espera ver {42}, mas em vez disso — um erro de formato ou uma string vazia. Familiar? Esta pergunta é uma das mais populares no Stack Overflow com milhares de visualizações. E hoje não vamos apenas dar a resposta, mas vamos olhar sob o capô do .NET para entender como funciona o escape de chaves em C#. Vamos lá!

\n\n

Problema: por que {{ não funciona como em outras linguagens?

\n\n

Em C#, as chaves {} são caracteres especiais em strings de formatação. Elas indicam onde começa e termina um placeholder para substituição de valor. Por exemplo, {0} significa "insira aqui o primeiro argumento".

\n\n

Mas e se precisarmos exibir as próprias chaves como texto? Na maioria das linguagens (Python, Java), o escape funciona através da duplicação: {{ resulta em {. Em C# — a mesma lógica, mas com um detalhe: duas chaves de abertura {{ se transformam em uma {, mas apenas se não fizerem parte de um placeholder válido.

\n\n

Exemplo da vida real: você está escrevendo um gerador de código em C# e precisa exibir a string if (x > 0) { return x; }. Se você simplesmente escrever:

\n\n
string template = "if (x > 0) { return x; }";
\n\n

O compilador ou String.Format interpretará { return x; } como uma tentativa de formatação e lançará uma exceção FormatException.

\n\n

Solução: escapando chaves corretamente em C#

\n\n

Método clássico: String.Format e StringBuilder

\n\n

A regra é simples: para exibir uma chave, escreva duas seguidas.

\n\n
// Exibirá: {Hello World}\nstring result = String.Format("{{Hello World}}");\nConsole.WriteLine(result); // {Hello World}
\n\n

Mas há uma nuance: se você precisar usar placeholders e chaves escapadas simultaneamente, a ordem é importante. Primeiro o escape, depois a substituição:

\n\n
int value = 42;\n// Exibirá: Valor {42} entre chaves\nstring result = String.Format("Valor {{{0}}} entre chaves", value);\nConsole.WriteLine(result); // Valor {42} entre chaves
\n\n

Vamos detalhar: {{{0}}} é {{ (uma chave) + {0} (placeholder) + }} (uma chave). Resultado: {42}.

\n\n

Interpolação de strings ($"...") — abordagem moderna

\n\n

A partir do C# 6, temos a interpolação de strings. Aqui o escape funciona de forma diferente — através da duplicação de chaves, mas sem placeholders internos:

\n\n
int value = 42;\n// Exibirá: Valor {42} entre chaves\nstring result = $"Valor {{{value}}} entre chaves";\nConsole.WriteLine(result); // Valor {42} entre chaves
\n\n

Observe: na interpolação {{ resulta em {, e {value} é a substituição. Tudo funciona intuitivamente, se você lembrar da regra: duas chaves — uma chave.

\n\n

Caso avançado: StringBuilder.AppendFormat

\n\n

Ao trabalhar com StringBuilder, use a mesma sintaxe:

\n\n
var sb = new StringBuilder();\nsb.AppendFormat("{{0}} = {0}", 123);\nConsole.WriteLine(sb.ToString()); // {0} = 123
\n\n

Como funciona internamente: análise do mecanismo de formatação

\n\n

Vamos dar uma olhada nos fontes do .NET (eles são abertos no GitHub!). Quando você chama String.Format, internamente é executado o método FormatHelper, que itera sobre os caracteres da string de formato.

\n\n

Algoritmo de parsing (simplificado)

\n<

Blogs

Book Recommendations