Curly Braces in C#: How to Escape and What's Inside

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: When the Code Starts to "Bend"

\n\n

Imagine: you're writing in C# and need to output a message like Value: {42}. You use String.Format("Value: {0}", 42) — and get the expected result. Now try to output just {42} without substitution. Naively writing:

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

You expect to see {42}, but instead get a format error or an empty string. Sound familiar? This question is one of the most popular on Stack Overflow with thousands of views. And today we won't just give the answer, but will look under the hood of .NET to understand how escaping curly braces works in C#. Let's go!

\n\n

The Problem: Why {{ Doesn't Work Like in Other Languages?

\n\n

In C#, curly braces {} are special characters in format strings. They indicate where a placeholder for value substitution begins and ends. For example, {0} means "insert the first argument here".

\n\n

But what if we need to output the curly braces themselves as text? In most languages (Python, Java), escaping works by doubling: {{ gives {. In C#, the logic is the same, but with a twist: two opening braces {{ turn into one {, but only if they are not part of a valid placeholder.

\n\n

A real-life example: you're writing a code generator in C# and need to output the string if (x > 0) { return x; }. If you simply write:

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

The compiler or String.Format will interpret { return x; } as an attempt at formatting and throw a FormatException.

\n\n

The Solution: Properly Escaping Curly Braces in C#

\n\n

The Classic Way: String.Format and StringBuilder

\n\n

The rule is simple: to output one curly brace, write two in a row.

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

But there's a nuance: if you need to use both placeholders and escaped braces simultaneously, the order matters. First escaping, then substitution:

\n\n
int value = 42;\n// Outputs: Value {42} in curly braces\nstring result = String.Format("Value {{{0}}} in curly braces", value);\nConsole.WriteLine(result); // Value {42} in curly braces
\n\n

Let's break it down: {{{0}}} is {{ (one brace) + {0} (placeholder) + }} (one brace). Result: {42}.

\n\n

String Interpolation ($"...") — The Modern Approach

\n\n

Starting with C# 6, we have string interpolation. Here, escaping works differently — through doubling the braces, but without placeholders inside:

\n\n
int value = 42;\n// Outputs: Value {42} in curly braces\nstring result = $"Value {{{value}}} in curly braces";\nConsole.WriteLine(result); // Value {42} in curly braces
\n\n

Note: in interpolation, {{ gives {, and {value} is a substitution. Everything works intuitively if you remember the rule: two braces — one brace.

\n\n

Advanced Case: StringBuilder.AppendFormat

\n\n

When working with StringBuilder, use the same syntax:

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

How It Works Under the Hood: Breakdown of the Formatting Mechanism

\n\n

Let's look into the .NET source code (it's open on GitHub!). When you call String.Format, the FormatHelper method is invoked internally, which iterates through the characters of the format string.

\n\n

Parsing Algorithm (Simplified)

\n<

Blogs

Book Recommendations