Llaves en C#: cómo escapar y qué hay dentro

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: cuando el código empieza a "torcerse"

\n\n

Imagine: está escribiendo en C#, necesita mostrar un mensaje como Valor: {42}. Usa String.Format("Valor: {0}", 42) — y obtiene el resultado esperado. Ahora intente mostrar simplemente {42} sin sustitución. Escribiendo ingenuamente:

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

Espera ver {42}, pero en su lugar obtiene un error de formato o una cadena vacía. ¿Le suena? Esta pregunta es una de las más populares en Stack Overflow con miles de visitas. Y hoy no solo daremos la respuesta, sino que miraremos bajo el capó de .NET para entender cómo funciona el escapado de llaves en C#. ¡Allá vamos!

\n\n

El problema: ¿por qué {{ no funciona como en otros lenguajes?

\n\n

En C#, las llaves {} son caracteres especiales en las cadenas de formato. Indican dónde comienza y termina un marcador de posición para la sustitución de un valor. Por ejemplo, {0} significa "inserta aquí el primer argumento".

\n\n

Pero, ¿qué pasa si necesitamos mostrar las propias llaves como texto? En la mayoría de los lenguajes (Python, Java), el escapado funciona duplicando: {{ da {. En C#, la lógica es la misma, pero con un truco: dos llaves de apertura {{ se convierten en una {, pero solo si no forman parte de un marcador de posición válido.

\n\n

Ejemplo de la vida real: está escribiendo un generador de código en C# y necesita mostrar la cadena if (x > 0) { return x; }. Si simplemente escribe:

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

El compilador o String.Format interpretará { return x; } como un intento de formateo y lanzará una excepción FormatException.

\n\n

Solución: escapado correcto de llaves en C#

\n\n

Método clásico: String.Format y StringBuilder

\n\n

La regla es simple: para mostrar una llave, escriba dos seguidas.

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

Pero hay un matiz: si necesita usar tanto marcadores de posición como llaves escapadas al mismo tiempo, el orden es importante. Primero el escapado, luego la sustitución:

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

Analicemos en detalle: {{{0}}} es {{ (una llave) + {0} (marcador de posición) + }} (una llave). Resultado: {42}.

\n\n

Interpolación de cadenas ($"...") — enfoque moderno

\n\n

A partir de C# 6, tenemos interpolación de cadenas. Aquí el escapado funciona de manera diferente: duplicando las llaves, pero sin marcadores de posición internos:

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

Observe: en la interpolación, {{ da {, y {value} es la sustitución. Todo funciona de forma intuitiva si recuerda la regla: dos llaves son una llave.

\n\n

Caso avanzado: StringBuilder.AppendFormat

\n\n

Cuando trabaje con StringBuilder, use la misma sintaxis:

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

Cómo funciona internamente: análisis del mecanismo de formato

\n\n

Miremos dentro del código fuente de .NET (¡está abierto en GitHub!). Cuando llama a String.Format, internamente se ejecuta el método FormatHelper, que itera sobre los caracteres de la cadena de formato.

\n\n

Algoritmo de análisis (simplificado)

\n<

Blogs

Book Recommendations