Question
How can I display a literal curly brace character when using String.Format in C#?
For example, consider this code:
sb.AppendLine(String.Format(
"public {0} {1} { get; private set; }",
prop.Type,
prop.Name
));
I want the generated output to be:
public Int32 MyProperty { get; private set; }
What is the correct way to include literal { and } characters in a String.Format format string?
Short Answer
By the end of this page, you will understand why curly braces have special meaning in C# String.Format, how to escape them correctly, and how to safely generate strings that contain both placeholders and literal braces.
Concept
In C#, String.Format uses curly braces to mark placeholders.
A placeholder looks like this:
{0}
{1}
{2}
These placeholders tell String.Format where to insert values.
For example:
string result = String.Format("Hello, {0}!", "Sam");
// result = "Hello, Sam!"
Because braces are part of the formatting syntax, writing a single { or } directly in the format string is not treated as normal text. Instead, String.Format tries to interpret it as part of a placeholder.
That is why this causes a problem:
String.Format("public {0} {1} { get; private set; }", prop.Type, prop.Name)
The braces around get; private set; are read as formatting syntax, not as literal characters.
The rule
To output a literal brace in String.Format, you must :
Mental Model
Think of String.Format like a template machine.
- Single braces mean: "insert something here"
- Double braces mean: "print an actual brace character"
So:
"Name: {0}"
means:
- find placeholder
0 - insert the first value
But:
"{{ Hello }}"
means:
{{becomes{}}becomes}- final output is
{ Hello }
A simple analogy: placeholders are like special command markers. If you want to print the marker itself, you must escape it by doubling it.
Syntax and Examples
The basic syntax of String.Format is:
String.Format("text {0} more text {1}", value1, value2)
Escaping braces
Use doubled braces for literal output:
String.Format("{{0}}")
Output:
{0}
Your example
string result = String.Format(
"public {0} {1} {{ get; private set; }}",
"Int32",
"MyProperty"
);
Console.WriteLine(result);
Output:
public Int32 MyProperty { get; private set; }
Another example
string message = String.Format("User {{ ID: {0}, Name: {1} }}", 42, "Ava");
Console.WriteLine(message);
Output:
Step by Step Execution
Consider this code:
string text = String.Format("public {0} {1} {{ get; private set; }}", "Int32", "MyProperty");
Here is what happens step by step:
String.Formatreads the format string.- It sees
{0}and replaces it with the first value:"Int32". - It sees
{1}and replaces it with the second value:"MyProperty". - It sees
{{and converts it to a literal{. - It keeps the text
get; private set;as normal text. - It sees
}}and converts it to a literal}. - The final result becomes:
public Int32 MyProperty { get; private set; }
Small trace example
s = String.Format(, );
Real World Use Cases
Escaping braces in String.Format is useful whenever your output contains text with {} characters.
1. Generating C# code
string code = String.Format(
"public {0} {1} {{ get; set; }}",
"string",
"Name"
);
Useful for code generators, scaffolding tools, or templates.
2. Creating structured log messages
string log = String.Format("Request {{ Id: {0}, Status: {1} }}", 123, "OK");
Useful when you want readable logs with grouped values.
3. Building JSON-like or config-like output
string jsonLike = String.Format("{{ \"id\": {0}, \"name\": \"{1}\" }}", 1, "Alice");
Even if you should use a serializer for real JSON, this still helps explain the formatting rule.
4. Template generation
string template = String.Format("function {0}() {{ return true; }}", "isReady");
Real Codebase Usage
In real projects, developers often use brace escaping in these situations:
Code generation
Applications that generate classes, properties, methods, or configuration files frequently build strings containing braces.
var line = String.Format("public {0} {1} {{ get; set; }}", typeName, propertyName);
Logging and diagnostics
When output format matters, developers may build readable strings with labeled values.
var msg = String.Format("Order {{ Id: {0}, Total: {1} }}", order.Id, order.Total);
Guarding against formatting errors
If a string contains braces that are not placeholders, developers escape them early to avoid runtime exceptions.
Common patterns in real code
- Template strings for generated files
- Validation output that wraps values in braces for clarity
- Error handling where formatted messages include structured text
- Early refactoring from
String.Formatto interpolation when readability improves
For newer C# code, many developers prefer string interpolation for readability:
$"public {prop.Type} {prop.Name} {{ get; private set; }}"
But the same brace escaping rule still applies: literal braces must still be doubled.
Common Mistakes
1. Using single braces for literal output
Broken code:
String.Format("public {0} {1} { get; private set; }", "Int32", "MyProperty")
Why it fails:
String.Formattreats{ get; private set; }as formatting syntax.- This leads to a format error.
Fix:
String.Format("public {0} {1} {{ get; private set; }}", "Int32", "MyProperty")
2. Escaping only one side
Broken code:
String.Format("Value: {{ {0} }", 10)
Why it fails:
- Opening brace is escaped correctly.
- Closing brace is not.
Fix:
String.Format("Value: {{ {0} }}", 10)
3. Forgetting that placeholders also use braces
Broken code:
String.Format(, , )
Comparisons
| Approach | Example | Best for | Notes |
|---|---|---|---|
String.Format | String.Format("Hello {0}", name) | Older code, indexed placeholders | Literal braces must be doubled |
| String interpolation | $"Hello {name}" | Modern C# code | Usually easier to read; literal braces still doubled |
| String concatenation | "Hello " + name | Very simple cases | Harder to read for complex strings |
| Verbatim strings | @"C:\Temp" | Paths and multiline text | Does not change String.Format brace rules |
vs string interpolation
Cheat Sheet
Quick rule
In C# format strings:
{{=>{}}=>}
Placeholder syntax
String.Format("{0}", value)
String.Format("{0} {1}", first, second)
Literal brace examples
String.Format("{{") // "{"
String.Format("}}") // "}"
String.Format("{{0}}") // "{0}"
Combined example
String.Format("public {0} {1} {{ get; set; }}", "int", "Age")
Output:
public int Age { get; set; }
Common error
FAQ
How do you escape curly braces in C# String.Format?
Use doubled braces:
{{for{}}for}
Why does String.Format treat braces specially?
Because braces define placeholders such as {0} and {1} where values are inserted.
Can I use backslashes to escape braces in C# format strings?
No. In String.Format, braces are escaped by doubling them, not with backslashes.
Does string interpolation also require escaped braces?
Yes. In interpolated strings, literal braces must also be written as {{ and }}.
What exception happens if braces are not escaped correctly?
You typically get a FormatException because the format string is invalid.
Is String.Format still used in modern C#?
Yes, especially in older codebases or APIs that expect format strings. However, string interpolation is often more readable in new code.
Mini Project
Description
Build a small C# program that generates property declarations as strings. This demonstrates how String.Format works when placeholders and literal braces appear in the same output.
Goal
Create a program that prints multiple valid C# property declarations using escaped braces in String.Format.
Requirements
- Create a class or simple data structure to hold a property type and name.
- Generate at least three property declaration lines.
- Use
String.Formatto insert the type and name. - Output literal
{and}characters correctly. - Print the generated lines to the console.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
Best Way to Repeat a Character in C#: Building Repeated Strings Efficiently
Learn the best way to repeat a character in C#, compare StringBuilder, string concatenation, and simpler built-in options.
C# Array Initialization Syntaxes Explained
Learn all common C# array initialization syntaxes with examples, rules, comparisons, and mistakes beginners often make.