C# String Format() Method

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
String Methods

What You’ll Learn

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.

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).

📝 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.

⚡ Quick Reference

GoalCode
Basic placeholdersstring.Format("Hi {0}, score {1}", name, score)
Currencystring.Format("Total: {0:C}", 19.99)
Two decimalsstring.Format("Avg: {0:N2}", 3.14159)
Short datestring.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

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);
    }
}

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.

C#
using System;

class Program {
    static void Main() {
        decimal price    = 49.5m;
        double completion = 0.875;

        string line1 = string.Format("Price:    {0:C}", price);
        string line2 = string.Format("Rounded:  {0:N2}", price);
        string line3 = string.Format("Progress: {0:P0}", completion);

        Console.WriteLine(line1);
        Console.WriteLine(line2);
        Console.WriteLine(line3);
    }
}

How It Works

{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);
    }
}

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);
    }
}

How It Works

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);
    }
}

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.

🚀 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 outputConsole.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.

📝 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.

⚡ 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.

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.

💡 Best Practices

✅ Do

  • 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

Key Takeaways

Knowledge Unlocked

Five things to remember about Format()

Use these points whenever you format strings in C#.

5
Core concepts
🔢 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.

Keep Building C# String Skills

Master template-based formatting with Format(), then continue to GetEnumerator() for character iteration.

Next: GetEnumerator() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful