Por que as chaves em C# são uma dor de cabeça?
Você já escreveu código em C#, quis exibir um texto como {Nome}: {Valor}, e em vez disso recebeu um FormatException? Se sim — você não está sozinho. A pergunta «How to escape curly brace in String.Format» no Stack Overflow acumulou dezenas de milhares de visualizações. E não é por acaso: as chaves {} em C# têm um significado especial — elas indicam um local para substituição de variáveis.
Mas o que fazer se você precisar exibir as próprias chaves como caracteres comuns? Por exemplo, para JSON, templates, geração de código ou apenas para uma formatação bonita de relatório? Hoje vamos abordar este tópico do início ao fim: desde o escape simples até truques avançados com StringBuilder e interpolação de strings.
Como escapar chaves: regra básica
A resposta é simples e elegante: duplique a chave. Se você quiser exibir uma chave de abertura {, escreva {{. Para a chave de fechamento } — }}. O C# entenderá que não é um placeholder, mas um caractere comum.
Aqui está o exemplo mais simples:
string result = string.Format("Valor entre chaves: {{0}}", 42);Console.WriteLine(result);// Saída: Valor entre chaves: {0}Observe: {{0}} não é um placeholder, mas um par de chaves escapadas com o dígito 0 dentro. Se tivéssemos escrito {0}, teríamos obtido o valor da variável (o número 42).
Erro típico de iniciante
Frequentemente, iniciantes escrevem assim:
// ERRO!string bad = string.Format("Olá, {name}!", name);// FormatException: Input string was not in a correct format.Por quê? Porque o C# espera um índice numérico dentro das chaves ({0}, {1}), e não um nome de variável. Para nomes, você deve usar interpolação de strings (mais sobre isso abaixo) ou especificar índices explicitamente.
Exemplos práticos: do simples ao complexo
Vamos analisar alguns cenários reais onde o escape de chaves é necessário.
1. Exibição de JSON ou XML para depuração
Imagine que você está escrevendo um logger e quer exibir uma string JSON com substituição de valor:
int userId = 101;string json = string.Format("{{\\"userId\\": {0}, \\"name\\": \\"Alice\\"}}", userId);Console.WriteLine(json);// Saída: {"userId": 101, "name": "Alice"}Aqui, {{ e }} criam as chaves externas do JSON, e {0} substitui o número.
2. Geração de templates de código
Suponha que você está escrevendo um gerador de código em C#. Precisa criar uma string com um template para outra linguagem (por exemplo, Python ou JavaScript):
string template = string.Format("def {0}(): return {{0}}", "calculate");Console.WriteLine(template);// Saída:// def calculate():// return {0}Observe: {{0}} na string de saída não é mais um placeholder do C#, mas parte do código gerado (por exemplo, para Python).
3. Formatação com múltiplos placeholders e chaves
Quando é necessário misturar substituições e escape, o importante é não se confundir com os índices:
string name = "Bob";int age = 30;string message = string.Format("Usuário {{ {0} }} (idade: {1})", name, age);Console.WriteLine(message);// Saída: Usuário { Bob } (idade: 30)Aqui, {{ produz {, }} produz }, e {0} e {1} substituem os valores.
Alternativas ao String.Format: interpolação de strings e StringBuilder
Embora string.Format seja um clássico, no C# moderno existem maneiras mais convenientes. Vamos comparar.
Interpolação de strings (C# 6+)
Interpolação é a mágica do $ antes da string. Ela é mais legível, mas o escape de chaves permanece