String Interpolation $"..." (C#)
In C#, $"..." (string interpolation) lets you embed variables and expressions inside a string using {}. It is more readable than the traditional string.Format() or + concatenation, and supports format specifiers and conditional expressions inline. This page also covers combining it with @"..." (verbatim strings) and the raw string literals added in C# 11.
Syntax
$"text {variable} text"
// Format specifiers go after a colon (same syntax as string.Format).
$"{variable:formatSpecifier}"
// Conditional expressions (ternary operator) can be embedded directly.
$"{condition ? valueIfTrue : valueIfFalse}"
// Combining @ and $ creates a verbatim interpolated string (backslashes are not escaped).
$@"path: {variable}\folder"
// Or (since C# 8.0, the order of @ and $ can be reversed with the same result):
@$"path: {variable}\folder"
// Raw string literals (C# 11, delimited by """) also support interpolation.
// Use the $""" form; the number of $ signs controls the interpolation delimiter.
$"""
text {variable} text
"""
Format Specifiers
| Specifier | Description | Example (value: 12345.6789) |
|---|---|---|
| :F2 | Fixed-point with 2 decimal places. | 12345.68 |
| :N0 | Integer with thousands separator. | 12,346 |
| :N2 | Thousands separator with 2 decimal places. | 12,345.68 |
| :E2 | Scientific notation with 2 decimal places. | 1.23E+004 |
| :P1 | Percentage with 1 decimal place (value: 0.856). | 85.6% |
| :D5 | Integer zero-padded to at least 5 digits (value: 42). | 00042 |
| :X | Hexadecimal (uppercase) (value: 255). | FF |
| :yyyy/MM/dd | Date format (DateTime type). | 2026/03/27 |
Sample Code
StringInterpolationBasic.cs
using System;
class StringInterpolationBasic {
static void Main() {
// Simply write a variable inside { } in a $-prefixed string to embed it.
string name = "item_x";
int score = 850;
string category = "type_A";
// Traditional + concatenation (tends to be hard to read).
string old = "Name: " + name + ", Score: " + score + ", Category: " + category;
// String interpolation makes it clear at a glance.
string msg = $"Name: {name}, Score: {score}, Category: {category}";
Console.WriteLine(old);
Console.WriteLine(msg);
int baseScore = 850;
int multiplier = 50;
// You can embed arithmetic directly, not just variables.
Console.WriteLine($"Total score: {baseScore * multiplier:N0}");
double damageRate = 0.856;
double totalDmg = 123456.789;
// :P1 formats as a percentage with 1 decimal place.
Console.WriteLine($"Hit rate: {damageRate:P1}");
// :F2 formats as a fixed-point number with 2 decimal places.
Console.WriteLine($"Total damage: {totalDmg:F2}");
// :N0 formats as an integer with thousands separators.
Console.WriteLine($"Total damage (grouped): {totalDmg:N0}");
}
}
This produces the following output:
dotnet script StringInterpolationBasic.cs Name: item_x, Score: 850, Category: type_A Name: item_x, Score: 850, Category: type_A Total score: 42,500 Hit rate: 85.6 % Total damage: 123456.79 Total damage (grouped): 123,457
StringInterpolationExpression.cs
using System;
using System.Collections.Generic;
class StringInterpolationExpression {
static void Main() {
// For long conditions, extracting to a variable improves readability,
// but short conditions can be written inline.
int score = 850;
Console.WriteLine($"Result: {(score >= 800 ? "Pass" : "Fail")}");
string name = " item_x ";
// Methods like Trim() and ToUpper() can be called directly inside { }.
Console.WriteLine($"Name (trimmed): {name.Trim()}");
Console.WriteLine($"Name (uppercase): {name.Trim().ToUpper()}");
var items = new List<string> { "item_a", "item_b", "item_c", "item_d", "item_e" };
// Reference the .Count property from inside { }.
Console.WriteLine($"Number of items: {items.Count}");
// Indexers work as well.
Console.WriteLine($"First item: {items[0]}");
// Format several values together, like a status display.
string target = "item_b";
int current = 42000;
int max = 50000;
double rate = (double)current / max;
// :N0 for thousands separator, :P1 for percentage, :D5 for zero-padding.
Console.WriteLine($"[{target}] Value: {current:N0} / {max:N0} ({rate:P1})");
Console.WriteLine($"Serial No: {42:D5}");
}
}
This produces the following output:
dotnet script StringInterpolationExpression.cs Result: Pass Name (trimmed): item_x Name (uppercase): ITEM_X Number of items: 5 First item: item_a [item_b] Value: 42,000 / 50,000 (84.0 %) Serial No: 00042
StringInterpolationVerbatim.cs
using System;
class StringInterpolationVerbatim {
static void Main() {
// In regular strings, backslashes must be escaped.
string name = "item_x";
// Regular string: you must write \\ to get a single backslash in the path.
string pathNormal = "C:\\Users\\" + name + "\\SaveData\\data.dat";
Console.WriteLine(pathNormal);
// Combining $@ lets you write \ as-is (verbatim interpolated string).
// Since C# 8.0, $@ and @$ are interchangeable.
string pathVerbatim = $@"C:\Users\{name}\SaveData\data.dat";
Console.WriteLine(pathVerbatim);
// Verbatim strings also work for multi-line text.
string target = "item_c";
int groupId = 3;
string report = $@"=== Processing Report ===
Subject: {name}
Related: {target}
Group: {groupId}";
Console.WriteLine(report);
// A single { or } is interpreted as the start of an interpolation hole.
Console.WriteLine($"Interpolation syntax: ${{variableName}}");
}
}
This produces the following output:
dotnet script StringInterpolationVerbatim.cs
C:\Users\item_x\SaveData\data.dat
C:\Users\item_x\SaveData\data.dat
=== Processing Report ===
Subject: item_x
Related: item_c
Group: 3
Interpolation syntax: ${variableName}
StringInterpolationRawLiteral.cs
using System;
// Requires .NET 7 / C# 11 or later.
class StringInterpolationRawLiteral {
static void Main() {
// Strings delimited by """. You can write { }, \, and quotes without escaping.
// Adding $ enables string interpolation.
string name = "item_x";
int score = 42500;
// Prefix with $$ so that {{ }} becomes the interpolation delimiter and { } is output as-is.
// Leading indentation up to the closing """ is stripped automatically.
string json = $$"""
{
"name": "{{name}}",
"score": {{score}}
}
""";
Console.WriteLine(json);
// With $$, {{ variable }} is interpolated; a single { } is output as-is.
// This is well suited for text like JSON where { } and variable embedding coexist.
string target = "item_b";
string template = $$"""
{
"target": "{{target}}",
"note": "Score is managed via a variable, not {score}"
}
""";
Console.WriteLine(template);
}
}
This produces the following output:
dotnet script StringInterpolationRawLiteral.cs
{
"name": "item_x",
"score": 42500
}
{
"target": "item_b",
"note": "Score is managed via a variable, not {score}"
}
Common Mistakes
Forgetting the $ prefix so {variable} is output literally
If you forget the $ prefix at the start of the string literal, the {} content is not interpolated and is output as plain text. This does not cause a compile error, so it can be easy to miss.
string name = "test_user";
// No $ prefix, so {name} is output as-is.
string msg = "Hello, {name}!";
Console.WriteLine(msg); // Hello, {name}!
// Correct: add the $ prefix.
string msgOk = $"Hello, {name}!";
Console.WriteLine(msgOk); // Hello, test_user!
Forgetting to escape { } when outputting them as literals
To output a literal { or } inside a $"..." string, you must double them as {{ }}. A single brace causes a compile error.
int x = 10;
// Compile error: } is not escaped.
// string bad = $"value = {x}, format: {0}";
// Correct: escape with {{ }}.
string ok = $"value = {x}, format: {{0}}";
Console.WriteLine(ok); // value = 10, format: {0}
Overview
String interpolation ($"...") in C# was introduced in C# 6.0. It provides a more readable alternative to string.Format("{0}, {1}", name, power). Inside {}, you can write not just variables, but any expression — method calls, arithmetic, property access, ternary operators, and more.
Format specifiers use the syntax {variable:format} with the same format strings as string.Format. Commonly used specifiers include thousands separator (:N0), decimal places (:F2), zero-padding (:D5), and percentage (:P1).
Combining @"..." (verbatim string) with interpolation as $@"..." is convenient for file paths and multi-line text. To output a literal { or }, write it doubled as {{ or }}.
Raw string literals in C# 11 ($"""...""") are well suited for text that contains many special characters, such as JSON, SQL, or HTML. Increasing the number of $ signs changes the interpolation delimiter to {{...}}, allowing {} to appear in the output without escaping. For advanced text formatting, also see PadLeft() / PadRight() and Split() / Join(). When a null variable is embedded in $"...", it is output as an empty string. To check for null beforehand, see IsNullOrEmpty() / IsNullOrWhiteSpace().
If you find any errors or copyright issues, please contact us.