The static method string.Format() builds a new string from a template with numbered placeholders like {0} and {1}. Each placeholder is replaced by a formatted value—perfect for messages, reports, currency, dates, and any output that mixes fixed text with variables.
01
Static Method
string.Format(...)
02
Placeholders
{0}, {1}, {2}…
03
New String
Formatted result.
04
Specifiers
C, N2, P, d…
05
vs Interpolation
When to use each.
06
Culture
IFormatProvider.
Fundamentals
Definition and Usage
In C#, string.Format() uses a composite format string. Curly braces mark where values go: {0} for the first argument, {1} for the second, and so on. The method returns one new string with every placeholder filled in.
You can add format specifiers inside placeholders to control how numbers and dates appear—for example {0:C} for currency or {0:N2} for a number with two decimal places. This is more readable than chaining + operators or manual rounding.
💡
Beginner Tip
Modern C# often uses string interpolation: $"Hello, {name}" instead of string.Format("Hello, {0}", name). Both work—learn Format() because it appears in older code, resource files, and APIs like Console.WriteLine(format, args).
Foundation
📝 Syntax
Common overloads on System.String:
C#
public static string Format(string format, params object[] args);
public static string Format(IFormatProvider provider, string format, params object[] args);
Parameters
format — template with placeholders {index} or {index:format}. Use {{ and }} for literal braces.
args — values inserted at matching indices. null becomes an empty string.
provider — optional culture/rules (e.g. CultureInfo.InvariantCulture) for number and date formatting.
Return Value
A new string with all placeholders replaced by formatted argument values.
Cheat Sheet
⚡ Quick Reference
Goal
Code
Basic placeholders
string.Format("Hi {0}, score {1}", name, score)
Currency
string.Format("Total: {0:C}", 19.99)
Two decimals
string.Format("Avg: {0:N2}", 3.14159)
Short date
string.Format("Due: {0:d}", DateTime.Today)
Interpolation equivalent
$"Hi {name}, score {score}"
Placeholder
{0} {1} {2}
Zero-based index
Currency
{0:C}
Money format
Number
{0:N2}
2 decimal places
Literal {
{{ brace }}
Escape braces
Hands-On
Examples Gallery
Run with dotnet run. Each example shows a practical use of Format()—from simple placeholders to numbers, dates, interpolation comparison, and culture-aware output.
📚 Getting Started
Replace placeholders with variable values.
Example 1 — Basic Format() Usage
Build a greeting message with name and age placeholders.
C#
using System;
class Program {
static void Main() {
string name = "John";
int age = 30;
string message = string.Format(
"Hello, my name is {0} and I'm {1} years old.",
name, age);
Console.WriteLine(message);
}
}
📤 Output:
Hello, my name is John and I'm 30 years old.
How It Works
{0} is replaced by name and {1} by age. Indices are zero-based and match the order of arguments after the format string. You can reuse an index: {0} twice would print the name twice.
Example 2 — Number Format Specifiers
Format prices and percentages with built-in specifiers inside placeholders.
{0:C} applies currency format, {0:N2} shows a number with two decimal places and grouping separators, and {0:P0} shows a percentage with zero decimal places. Output depends on the current culture (here, typical US formatting).
📈 Practical Patterns
Dates, interpolation, and culture-specific formatting.
Example 3 — Date and Time Formatting
Insert a DateTime value with standard date/time patterns.
C#
using System;
class Program {
static void Main() {
DateTime due = new DateTime(2026, 12, 25);
string shortDate = string.Format("Due date: {0:d}", due);
string longDate = string.Format("Full: {0:D}", due);
string timeStamp = string.Format("Logged: {0:yyyy-MM-dd HH:mm}", due);
Console.WriteLine(shortDate);
Console.WriteLine(longDate);
Console.WriteLine(timeStamp);
}
}
📤 Output:
Due date: 12/25/2026
Full: Thursday, December 25, 2026
Logged: 2026-12-25 00:00
How It Works
Standard format strings like d, D, and custom patterns like yyyy-MM-dd go inside the placeholder after a colon. The same patterns work in string interpolation: $"{due:d}".
Example 4 — Format() vs String Interpolation
Two ways to produce the same output—pick the clearer one for your situation.
C#
using System;
class Program {
static void Main() {
string lang = "C#";
int version = 12;
string viaFormat = string.Format(
"Language: {0}, Version: {1}", lang, version);
string viaInterp = $"Language: {lang}, Version: {version}";
Console.WriteLine(viaFormat);
Console.WriteLine(viaInterp);
}
}
Interpolation is compiled to a similar formatting call under the hood. Use $"..." in source code for readability. Use string.Format when the template string is loaded at runtime (config, database, resource file).
Example 5 — Culture-Specific Formatting
Pass IFormatProvider to control currency symbols and separators.
C#
using System;
using System.Globalization;
class Program {
static void Main() {
decimal amount = 1234.56m;
string us = string.Format(
CultureInfo.GetCultureInfo("en-US"),
"US: {0:C}", amount);
string de = string.Format(
CultureInfo.GetCultureInfo("de-DE"),
"DE: {0:C}", amount);
string invariant = string.Format(
CultureInfo.InvariantCulture,
"Inv: {0:N2}", amount);
Console.WriteLine(us);
Console.WriteLine(de);
Console.WriteLine(invariant);
}
}
📤 Output:
US: $1,234.56
DE: 1.234,56 €
Inv: 1,234.56
How It Works
The overload Format(IFormatProvider, string, params object[]) applies culture rules to numeric and date placeholders. Use InvariantCulture for logs and file formats that must look the same on every machine.
Applications
🚀 Common Use Cases
User messages — combine labels with dynamic names, counts, or status text.
Financial output — format currency and percentages in invoices or reports.
Log lines — structured text with timestamps and values: "[{0:HH:mm:ss}] {1}".
Resource strings — templates in .resx files filled at runtime with Format.
Console output — Console.WriteLine(format, arg0, arg1) uses the same composite formatting rules.
🧠 How Format() Works
1
You pass a format template
A string with {0}, {1}, … plus optional specifiers.
Template
2
Runtime maps indices to args
Each placeholder index picks the matching argument value.
Bind
3
Values are formatted
Numbers, dates, and objects use ToString(format) or culture rules.
Format
=
📝
New string returned
Complete message with every placeholder replaced by its formatted text.
Important
📝 Notes
Placeholders use zero-based indices: {0}, {1}, …
Escape literal braces by doubling them: {{ and }}.
null arguments are rendered as empty strings, not the text "null".
Wrong or missing indices throw FormatException at runtime.
Alignment syntax: {0,10} right-align in 10 chars; {0,-10} left-align.
Console.WriteLine("Hi {0}", name) follows the same composite formatting rules.
Performance
⚡ Optimization
Format() and string interpolation are both efficient for typical output. For many small concatenations in a tight loop, consider StringBuilder or collecting lines first. When the format string is constant and arguments are simple, interpolation is usually the most readable choice with no performance penalty. Use InvariantCulture when culture-independent output avoids repeated locale lookups in server code.
Wrap Up
Conclusion
The C# Format() method is a flexible way to build strings from templates with numbered placeholders and rich format specifiers for numbers and dates. It remains essential for resource files, dynamic templates, and culture-aware output.
Practice the examples above, compare with string interpolation, then continue to GetEnumerator() to learn how strings expose character iteration.
Use meaningful format strings in resource files with Format
Apply format specifiers (C, N2, d) inside placeholders
Use InvariantCulture for logs and portable file formats
Prefer $"..." for inline templates in source code
Match placeholder count to the arguments you pass
❌ Don’t
Hard-code user-visible templates when localization is needed
Forget to escape { and } when you need literal braces
Assume currency/date output is the same on all cultures
Use Format with wrong index order—verify {0}, {1}
Build complex strings with many + when one template suffices
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about Format()
Use these points whenever you format strings in C#.
5
Core concepts
📝01
Static Method
string.Format(...)
Basics
🔢02
{0} {1}
Indexed slots.
Placeholders
💰03
Specifiers
C, N2, P, d.
Numbers
🗣04
vs $""
Interpolation.
Modern C#
🌐05
Culture
IFormatProvider.
Locale
❓ Frequently Asked Questions
Format() builds a new string from a template with placeholders like {0} and {1}, replacing each placeholder with a formatted value. Call it as string.Format("Hello, {0}", name). It is static—you do not call it on an instance.
string.Format(format, arg0, arg1, ...) where format contains indexed placeholders {0}, {1}, etc. Example: string.Format("Price: {0:C}", price) formats a number as currency.
It returns a new string with all placeholders replaced by the string representation of each argument. Original arguments are unchanged. null arguments are inserted as empty strings.
They are zero-based placeholders. {0} is replaced by the first argument after the format string, {1} by the second, and so on. You can reuse an index: {0} may appear multiple times in the same template.
Both produce formatted strings. Interpolation ($"Hello, {name}") is often clearer for everyday code. Use Format() when the template comes from a variable, config file, or resource string, or when you need IFormatProvider/culture overloads explicitly.
Add a format specifier inside the placeholder: {0:N2} for a number with two decimals, {0:C} for currency, {0:d} for short date. Example: string.Format("Total: {0:C}", 49.5) might output Total: $49.50 depending on culture.
Did you know?
C# string interpolation ($"Value: {price:C}") is transformed by the compiler into a call equivalent to string.Format. Learning composite format syntax helps you read both styles and use the same specifiers in resource strings where $ literals are not available.