C#idiomatic C#
composite-formattingstandard/base-types

Core library

Composite formatting

Learn about .NET composite formatting, which takes as input a list of objects and a composite format string, containing fixed text with indexed placeholders.

  • page standard/base-types/composite-formatting
  • updated 10/22/2025

The .NET composite formatting feature takes a list of objects and a composite format string as input. A composite format string consists of fixed text intermixed with indexed placeholders, called format items. These format items correspond to the objects in the list. The formatting operation yields a result string that consists of the original fixed text intermixed with the string representation of the objects in the list.

The following methods support the composite formatting feature:

Composite format string

A composite format string and object list are used as arguments of methods that support the composite formatting feature. A composite format string consists of zero or more runs of fixed text intermixed with one or more format items. The fixed text is any string that you choose, and each format item corresponds to an object or boxed structure in the list. The string representation of each object replaces the corresponding format item.

Consider the following System.String.Format code fragment:

sample · csharpdocs/standard/base-types/snippets/composite-formatting/net/csharp/Program.csbasic

csharp
using System.Text;

void Index()
{
    // <index>
    string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                  2, 3, 5, 7);
    Console.WriteLine(primes);

    // The example displays the following output:
    //      Four prime numbers: 2, 3, 5, 7
    // </index>
}

void Multiple()
{
    // <multiple>
    string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                    Int64.MaxValue);
    Console.WriteLine(multiple);

    // The example displays the following output:
    //      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
    // </multiple>
}

void Alignment()
{
    // <alignment>
    string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                       "Ebenezer", "Francine", "George" };
    decimal[] hours = { 40, 6.667m, 40.39m, 82,
                        40.333m, 80, 16.75m };

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

    for (int counter = 0; counter < names.Length; counter++)
        Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

    // The example displays the following output:
    //      Name                 Hours
    //      
    //      Adam                  40.0
    //      Bridgette              6.7
    //      Carla                 40.4
    //      Daniel                82.0
    //      Ebenezer              40.3
    //      Francine              80.0
    //      George                16.8
    // </alignment>
}

void NowGood()
{
    // <now_good>
    int value = 6324;
    string output = string.Format("{{{0:D}}}", value);
    
    Console.WriteLine(output);
    // The example displays the following output:
    //       {6324}
    // </now_good>
}

void Examples_ToString()
{
    // <example_tostring>
    string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
    string formatString2 = DateTime.Now.ToString("dddd MMMM");
    // </example_tostring>
}

void Examples_Currency()
{
    // <example_currency>
    int myNumber = 100;
    Console.WriteLine($"{myNumber:C}");

    // The example displays the following output
    // if en-US is the current culture:
    //        $100.00
    // </example_currency>
}

void Examples_Multiple()
{
    // <example_multiple>
    string myName = "Fred";
    Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                    myName, DateTime.Now));

    // Depending on the current time, the example displays output like the following:
    //        Name = Fred, hours = 11, minutes = 30
    // </example_multiple>
}

void Examples_Bar()
{
    // <example_bar>
    string firstName = "Fred";
    string lastName = "Opals";
    int myNumber = 100;

    string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
    string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
    string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);
    Console.WriteLine();

    formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
    formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
    formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);

    // The example displays the following output on a system whose current
    // culture is en-US:
    //     First Name = |      Fred|
    //     Last Name =  |     Opals|
    //     Price =      |   $100.00|
    //
    //     First Name = |Fred      |
    //     Last Name =  |Opals     |
    //     Price =      |$100.00   |
    // </example_bar>
}

// <basic>
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
// </basic>

Index();
CompositeFormatDemo();
Multiple();
Alignment();
NowGood();

Examples_ToString();
Examples_Currency();
Examples_Multiple();
Examples_Bar();

void CompositeFormatDemo()
{
    // <compositeformat>
    // Typically stored as a static readonly field so it's parsed only once.
    CompositeFormat format = CompositeFormat.Parse("Name = {0}, hours = {1:hh}");

    // Pass null for IFormatProvider to use the current culture.
    // Use the pre-parsed format to avoid reparsing on every call.
    string result = string.Format(null, format, "Fred", DateTime.Now);
    Console.WriteLine(result);
    // Output: Name = Fred, hours = 06
    // </compositeformat>
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/net/vb/Program.vbbasic

vb
Imports System
Imports System.Text

Module Program
    Sub Main(args As String())
        '<basic>
        String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
        '</basic>

        Index()
        CompositeFormatDemo()
        Multiple()
        Alignment()
        NowGood()

        Examples_ToString()
        Examples_Currency()
        Examples_Multiple()
        Examples_Bar()
    End Sub

    Sub Index()
        '<index>
        Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                              2, 3, 5, 7)
        Console.WriteLine(primes)

        'The example displays the following output
        '     Four prime numbers 2, 3, 5, 7
        '</index>
    End Sub

    Sub Multiple()
        '<multiple>
        Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                               Int64.MaxValue)
        Console.WriteLine(multiple)

        'The example displays the following output
        '     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
        '</multiple>
    End Sub

    Sub Alignment()
        '<alignment>
        Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                                 "Ebenezer", "Francine", "George"}

        Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                                  40.333D, 80, 16.75D}

        Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

        For counter = 0 To names.Length - 1
            Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
        Next

        'The example displays the following output
        '     Name                 Hours
        '     
        '     Adam                  40.0
        '     Bridgette              6.7
        '     Carla                 40.4
        '     Daniel                82.0
        '     Ebenezer              40.3
        '     Francine              80.0
        '     George                16.8
        '</alignment>
    End Sub

    Sub NowGood()
        '<now_good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}", value)

        Console.WriteLine(output)

        'The example displays the following output
        '      {6324}
        '</now_good>
    End Sub

    Sub Examples_ToString()
        '<example_tostring>
        Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
        Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
        '</example_tostring>
    End Sub

    Sub Examples_Currency()
        '<example_currency>
        Dim myNumber As Integer = 100
        Console.WriteLine("{0:C}", myNumber)

        'The example displays the following output
        'if en-US Is the current culture:
        '       $100.00
        '</example_currency>
    End Sub

    Sub Examples_Multiple()
        '<example_multiple>
        Dim myName As String = "Fred"
        Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                        myName, DateTime.Now))
        'Depending on the current time, the example displays output Like the following:
        '       Name = Fred, hours = 11, minutes = 30
        '</example_multiple>
    End Sub

    Sub Examples_Bar()
        '<example_bar>
        Dim firstName As String = "Fred"
        Dim lastName As String = "Opals"
        Dim myNumber As Integer = 100

        Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
        Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
        Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)
        Console.WriteLine()

        formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
        formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
        formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)

        'The example displays the following output on a system whose current
        'culture Is en-US:
        '    First Name = |      Fred|
        '    Last Name =  |     Opals|
        '    Price =      |   $100.00|
        '
        '    First Name = |Fred      |
        '    Last Name =  |Opals     |
        '    Price =      |$100.00   |
        '</example_bar>
    End Sub

    Sub CompositeFormatDemo()
        '<compositeformat>
        ' Typically stored as a Shared ReadOnly field so it's parsed only once.
        Dim format As CompositeFormat = CompositeFormat.Parse("Name = {0}, hours = {1:hh}")

        ' Pass Nothing for IFormatProvider to use the current culture.
        ' Use the pre-parsed format to avoid reparsing on every call.
        Dim result As String = String.Format(Nothing, format, "Fred", DateTime.Now)
        Console.WriteLine(result)
        ' Output: Name = Fred, hours = 06
        '</compositeformat>
    End Sub

End Module

The fixed text is Name =  and , hours = . The format items are {0}, whose index of 0 corresponds to the string literal "Fred", and {1:hh}, whose index of 1 corresponds to the value of DateTime.Now.

Format item syntax

Each format item takes the following form and consists of the following components:

{index[,width][:formatString]}

The matching braces ({ and }) are required.

Index component

The mandatory index component, which is also called a parameter specifier, is a number starting from 0 that identifies a corresponding item in the list of objects. That is, the format item whose parameter specifier is 0 formats the first object in the list. The format item whose parameter specifier is 1 formats the second object in the list, and so on. The following example includes four parameter specifiers, numbered zero through three, to represent prime numbers less than 10:

sample · csharpdocs/standard/base-types/snippets/composite-formatting/net/csharp/Program.csindex

csharp
using System.Text;

void Index()
{
    // <index>
    string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                  2, 3, 5, 7);
    Console.WriteLine(primes);

    // The example displays the following output:
    //      Four prime numbers: 2, 3, 5, 7
    // </index>
}

void Multiple()
{
    // <multiple>
    string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                    Int64.MaxValue);
    Console.WriteLine(multiple);

    // The example displays the following output:
    //      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
    // </multiple>
}

void Alignment()
{
    // <alignment>
    string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                       "Ebenezer", "Francine", "George" };
    decimal[] hours = { 40, 6.667m, 40.39m, 82,
                        40.333m, 80, 16.75m };

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

    for (int counter = 0; counter < names.Length; counter++)
        Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

    // The example displays the following output:
    //      Name                 Hours
    //      
    //      Adam                  40.0
    //      Bridgette              6.7
    //      Carla                 40.4
    //      Daniel                82.0
    //      Ebenezer              40.3
    //      Francine              80.0
    //      George                16.8
    // </alignment>
}

void NowGood()
{
    // <now_good>
    int value = 6324;
    string output = string.Format("{{{0:D}}}", value);
    
    Console.WriteLine(output);
    // The example displays the following output:
    //       {6324}
    // </now_good>
}

void Examples_ToString()
{
    // <example_tostring>
    string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
    string formatString2 = DateTime.Now.ToString("dddd MMMM");
    // </example_tostring>
}

void Examples_Currency()
{
    // <example_currency>
    int myNumber = 100;
    Console.WriteLine($"{myNumber:C}");

    // The example displays the following output
    // if en-US is the current culture:
    //        $100.00
    // </example_currency>
}

void Examples_Multiple()
{
    // <example_multiple>
    string myName = "Fred";
    Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                    myName, DateTime.Now));

    // Depending on the current time, the example displays output like the following:
    //        Name = Fred, hours = 11, minutes = 30
    // </example_multiple>
}

void Examples_Bar()
{
    // <example_bar>
    string firstName = "Fred";
    string lastName = "Opals";
    int myNumber = 100;

    string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
    string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
    string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);
    Console.WriteLine();

    formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
    formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
    formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);

    // The example displays the following output on a system whose current
    // culture is en-US:
    //     First Name = |      Fred|
    //     Last Name =  |     Opals|
    //     Price =      |   $100.00|
    //
    //     First Name = |Fred      |
    //     Last Name =  |Opals     |
    //     Price =      |$100.00   |
    // </example_bar>
}

// <basic>
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
// </basic>

Index();
CompositeFormatDemo();
Multiple();
Alignment();
NowGood();

Examples_ToString();
Examples_Currency();
Examples_Multiple();
Examples_Bar();

void CompositeFormatDemo()
{
    // <compositeformat>
    // Typically stored as a static readonly field so it's parsed only once.
    CompositeFormat format = CompositeFormat.Parse("Name = {0}, hours = {1:hh}");

    // Pass null for IFormatProvider to use the current culture.
    // Use the pre-parsed format to avoid reparsing on every call.
    string result = string.Format(null, format, "Fred", DateTime.Now);
    Console.WriteLine(result);
    // Output: Name = Fred, hours = 06
    // </compositeformat>
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/net/vb/Program.vbindex

vb
Imports System
Imports System.Text

Module Program
    Sub Main(args As String())
        '<basic>
        String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
        '</basic>

        Index()
        CompositeFormatDemo()
        Multiple()
        Alignment()
        NowGood()

        Examples_ToString()
        Examples_Currency()
        Examples_Multiple()
        Examples_Bar()
    End Sub

    Sub Index()
        '<index>
        Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                              2, 3, 5, 7)
        Console.WriteLine(primes)

        'The example displays the following output
        '     Four prime numbers 2, 3, 5, 7
        '</index>
    End Sub

    Sub Multiple()
        '<multiple>
        Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                               Int64.MaxValue)
        Console.WriteLine(multiple)

        'The example displays the following output
        '     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
        '</multiple>
    End Sub

    Sub Alignment()
        '<alignment>
        Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                                 "Ebenezer", "Francine", "George"}

        Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                                  40.333D, 80, 16.75D}

        Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

        For counter = 0 To names.Length - 1
            Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
        Next

        'The example displays the following output
        '     Name                 Hours
        '     
        '     Adam                  40.0
        '     Bridgette              6.7
        '     Carla                 40.4
        '     Daniel                82.0
        '     Ebenezer              40.3
        '     Francine              80.0
        '     George                16.8
        '</alignment>
    End Sub

    Sub NowGood()
        '<now_good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}", value)

        Console.WriteLine(output)

        'The example displays the following output
        '      {6324}
        '</now_good>
    End Sub

    Sub Examples_ToString()
        '<example_tostring>
        Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
        Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
        '</example_tostring>
    End Sub

    Sub Examples_Currency()
        '<example_currency>
        Dim myNumber As Integer = 100
        Console.WriteLine("{0:C}", myNumber)

        'The example displays the following output
        'if en-US Is the current culture:
        '       $100.00
        '</example_currency>
    End Sub

    Sub Examples_Multiple()
        '<example_multiple>
        Dim myName As String = "Fred"
        Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                        myName, DateTime.Now))
        'Depending on the current time, the example displays output Like the following:
        '       Name = Fred, hours = 11, minutes = 30
        '</example_multiple>
    End Sub

    Sub Examples_Bar()
        '<example_bar>
        Dim firstName As String = "Fred"
        Dim lastName As String = "Opals"
        Dim myNumber As Integer = 100

        Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
        Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
        Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)
        Console.WriteLine()

        formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
        formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
        formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)

        'The example displays the following output on a system whose current
        'culture Is en-US:
        '    First Name = |      Fred|
        '    Last Name =  |     Opals|
        '    Price =      |   $100.00|
        '
        '    First Name = |Fred      |
        '    Last Name =  |Opals     |
        '    Price =      |$100.00   |
        '</example_bar>
    End Sub

    Sub CompositeFormatDemo()
        '<compositeformat>
        ' Typically stored as a Shared ReadOnly field so it's parsed only once.
        Dim format As CompositeFormat = CompositeFormat.Parse("Name = {0}, hours = {1:hh}")

        ' Pass Nothing for IFormatProvider to use the current culture.
        ' Use the pre-parsed format to avoid reparsing on every call.
        Dim result As String = String.Format(Nothing, format, "Fred", DateTime.Now)
        Console.WriteLine(result)
        ' Output: Name = Fred, hours = 06
        '</compositeformat>
    End Sub

End Module

Multiple format items can refer to the same element in the list of objects by specifying the same parameter specifier. For example, you can format the same numeric value in hexadecimal, scientific, and number format by specifying a composite format string such as "0x{0:X} {0:E} {0:N}", as the following example shows:

sample · csharpdocs/standard/base-types/snippets/composite-formatting/net/csharp/Program.csmultiple

csharp
using System.Text;

void Index()
{
    // <index>
    string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                  2, 3, 5, 7);
    Console.WriteLine(primes);

    // The example displays the following output:
    //      Four prime numbers: 2, 3, 5, 7
    // </index>
}

void Multiple()
{
    // <multiple>
    string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                    Int64.MaxValue);
    Console.WriteLine(multiple);

    // The example displays the following output:
    //      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
    // </multiple>
}

void Alignment()
{
    // <alignment>
    string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                       "Ebenezer", "Francine", "George" };
    decimal[] hours = { 40, 6.667m, 40.39m, 82,
                        40.333m, 80, 16.75m };

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

    for (int counter = 0; counter < names.Length; counter++)
        Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

    // The example displays the following output:
    //      Name                 Hours
    //      
    //      Adam                  40.0
    //      Bridgette              6.7
    //      Carla                 40.4
    //      Daniel                82.0
    //      Ebenezer              40.3
    //      Francine              80.0
    //      George                16.8
    // </alignment>
}

void NowGood()
{
    // <now_good>
    int value = 6324;
    string output = string.Format("{{{0:D}}}", value);
    
    Console.WriteLine(output);
    // The example displays the following output:
    //       {6324}
    // </now_good>
}

void Examples_ToString()
{
    // <example_tostring>
    string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
    string formatString2 = DateTime.Now.ToString("dddd MMMM");
    // </example_tostring>
}

void Examples_Currency()
{
    // <example_currency>
    int myNumber = 100;
    Console.WriteLine($"{myNumber:C}");

    // The example displays the following output
    // if en-US is the current culture:
    //        $100.00
    // </example_currency>
}

void Examples_Multiple()
{
    // <example_multiple>
    string myName = "Fred";
    Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                    myName, DateTime.Now));

    // Depending on the current time, the example displays output like the following:
    //        Name = Fred, hours = 11, minutes = 30
    // </example_multiple>
}

void Examples_Bar()
{
    // <example_bar>
    string firstName = "Fred";
    string lastName = "Opals";
    int myNumber = 100;

    string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
    string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
    string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);
    Console.WriteLine();

    formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
    formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
    formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);

    // The example displays the following output on a system whose current
    // culture is en-US:
    //     First Name = |      Fred|
    //     Last Name =  |     Opals|
    //     Price =      |   $100.00|
    //
    //     First Name = |Fred      |
    //     Last Name =  |Opals     |
    //     Price =      |$100.00   |
    // </example_bar>
}

// <basic>
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
// </basic>

Index();
CompositeFormatDemo();
Multiple();
Alignment();
NowGood();

Examples_ToString();
Examples_Currency();
Examples_Multiple();
Examples_Bar();

void CompositeFormatDemo()
{
    // <compositeformat>
    // Typically stored as a static readonly field so it's parsed only once.
    CompositeFormat format = CompositeFormat.Parse("Name = {0}, hours = {1:hh}");

    // Pass null for IFormatProvider to use the current culture.
    // Use the pre-parsed format to avoid reparsing on every call.
    string result = string.Format(null, format, "Fred", DateTime.Now);
    Console.WriteLine(result);
    // Output: Name = Fred, hours = 06
    // </compositeformat>
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/net/vb/Program.vbmultiple

vb
Imports System
Imports System.Text

Module Program
    Sub Main(args As String())
        '<basic>
        String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
        '</basic>

        Index()
        CompositeFormatDemo()
        Multiple()
        Alignment()
        NowGood()

        Examples_ToString()
        Examples_Currency()
        Examples_Multiple()
        Examples_Bar()
    End Sub

    Sub Index()
        '<index>
        Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                              2, 3, 5, 7)
        Console.WriteLine(primes)

        'The example displays the following output
        '     Four prime numbers 2, 3, 5, 7
        '</index>
    End Sub

    Sub Multiple()
        '<multiple>
        Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                               Int64.MaxValue)
        Console.WriteLine(multiple)

        'The example displays the following output
        '     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
        '</multiple>
    End Sub

    Sub Alignment()
        '<alignment>
        Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                                 "Ebenezer", "Francine", "George"}

        Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                                  40.333D, 80, 16.75D}

        Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

        For counter = 0 To names.Length - 1
            Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
        Next

        'The example displays the following output
        '     Name                 Hours
        '     
        '     Adam                  40.0
        '     Bridgette              6.7
        '     Carla                 40.4
        '     Daniel                82.0
        '     Ebenezer              40.3
        '     Francine              80.0
        '     George                16.8
        '</alignment>
    End Sub

    Sub NowGood()
        '<now_good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}", value)

        Console.WriteLine(output)

        'The example displays the following output
        '      {6324}
        '</now_good>
    End Sub

    Sub Examples_ToString()
        '<example_tostring>
        Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
        Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
        '</example_tostring>
    End Sub

    Sub Examples_Currency()
        '<example_currency>
        Dim myNumber As Integer = 100
        Console.WriteLine("{0:C}", myNumber)

        'The example displays the following output
        'if en-US Is the current culture:
        '       $100.00
        '</example_currency>
    End Sub

    Sub Examples_Multiple()
        '<example_multiple>
        Dim myName As String = "Fred"
        Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                        myName, DateTime.Now))
        'Depending on the current time, the example displays output Like the following:
        '       Name = Fred, hours = 11, minutes = 30
        '</example_multiple>
    End Sub

    Sub Examples_Bar()
        '<example_bar>
        Dim firstName As String = "Fred"
        Dim lastName As String = "Opals"
        Dim myNumber As Integer = 100

        Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
        Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
        Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)
        Console.WriteLine()

        formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
        formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
        formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)

        'The example displays the following output on a system whose current
        'culture Is en-US:
        '    First Name = |      Fred|
        '    Last Name =  |     Opals|
        '    Price =      |   $100.00|
        '
        '    First Name = |Fred      |
        '    Last Name =  |Opals     |
        '    Price =      |$100.00   |
        '</example_bar>
    End Sub

    Sub CompositeFormatDemo()
        '<compositeformat>
        ' Typically stored as a Shared ReadOnly field so it's parsed only once.
        Dim format As CompositeFormat = CompositeFormat.Parse("Name = {0}, hours = {1:hh}")

        ' Pass Nothing for IFormatProvider to use the current culture.
        ' Use the pre-parsed format to avoid reparsing on every call.
        Dim result As String = String.Format(Nothing, format, "Fred", DateTime.Now)
        Console.WriteLine(result)
        ' Output: Name = Fred, hours = 06
        '</compositeformat>
    End Sub

End Module

Each format item can refer to any object in the list. For example, if there are three objects, you can format the second, first, and third object by specifying a composite format string such as {1} {0} {2}. An object that isn't referenced by a format item is ignored. A System.FormatException is thrown at runtime if a parameter specifier designates an item outside the bounds of the list of objects.

Width component

The optional width component is a signed integer indicating the preferred formatted field width. If the value of width is less than the length of the formatted string, width is ignored, and the length of the formatted string is used as the field width. The formatted data in the field is right-aligned if width is positive and left-aligned if width is negative. If padding is necessary, white space is used. The comma is required if width is specified.

The following example defines two arrays, one containing the names of employees and the other containing the hours they worked over two weeks. The composite format string left-aligns the names in a 20-character field and right-aligns their hours in a 5-character field. The "N1" standard format string formats the hours with one fractional digit.

sample · csharpdocs/standard/base-types/snippets/composite-formatting/net/csharp/Program.csalignment

csharp
using System.Text;

void Index()
{
    // <index>
    string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                  2, 3, 5, 7);
    Console.WriteLine(primes);

    // The example displays the following output:
    //      Four prime numbers: 2, 3, 5, 7
    // </index>
}

void Multiple()
{
    // <multiple>
    string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                    Int64.MaxValue);
    Console.WriteLine(multiple);

    // The example displays the following output:
    //      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
    // </multiple>
}

void Alignment()
{
    // <alignment>
    string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                       "Ebenezer", "Francine", "George" };
    decimal[] hours = { 40, 6.667m, 40.39m, 82,
                        40.333m, 80, 16.75m };

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

    for (int counter = 0; counter < names.Length; counter++)
        Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

    // The example displays the following output:
    //      Name                 Hours
    //      
    //      Adam                  40.0
    //      Bridgette              6.7
    //      Carla                 40.4
    //      Daniel                82.0
    //      Ebenezer              40.3
    //      Francine              80.0
    //      George                16.8
    // </alignment>
}

void NowGood()
{
    // <now_good>
    int value = 6324;
    string output = string.Format("{{{0:D}}}", value);
    
    Console.WriteLine(output);
    // The example displays the following output:
    //       {6324}
    // </now_good>
}

void Examples_ToString()
{
    // <example_tostring>
    string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
    string formatString2 = DateTime.Now.ToString("dddd MMMM");
    // </example_tostring>
}

void Examples_Currency()
{
    // <example_currency>
    int myNumber = 100;
    Console.WriteLine($"{myNumber:C}");

    // The example displays the following output
    // if en-US is the current culture:
    //        $100.00
    // </example_currency>
}

void Examples_Multiple()
{
    // <example_multiple>
    string myName = "Fred";
    Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                    myName, DateTime.Now));

    // Depending on the current time, the example displays output like the following:
    //        Name = Fred, hours = 11, minutes = 30
    // </example_multiple>
}

void Examples_Bar()
{
    // <example_bar>
    string firstName = "Fred";
    string lastName = "Opals";
    int myNumber = 100;

    string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
    string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
    string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);
    Console.WriteLine();

    formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
    formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
    formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);

    // The example displays the following output on a system whose current
    // culture is en-US:
    //     First Name = |      Fred|
    //     Last Name =  |     Opals|
    //     Price =      |   $100.00|
    //
    //     First Name = |Fred      |
    //     Last Name =  |Opals     |
    //     Price =      |$100.00   |
    // </example_bar>
}

// <basic>
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
// </basic>

Index();
CompositeFormatDemo();
Multiple();
Alignment();
NowGood();

Examples_ToString();
Examples_Currency();
Examples_Multiple();
Examples_Bar();

void CompositeFormatDemo()
{
    // <compositeformat>
    // Typically stored as a static readonly field so it's parsed only once.
    CompositeFormat format = CompositeFormat.Parse("Name = {0}, hours = {1:hh}");

    // Pass null for IFormatProvider to use the current culture.
    // Use the pre-parsed format to avoid reparsing on every call.
    string result = string.Format(null, format, "Fred", DateTime.Now);
    Console.WriteLine(result);
    // Output: Name = Fred, hours = 06
    // </compositeformat>
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/net/vb/Program.vbalignment

vb
Imports System
Imports System.Text

Module Program
    Sub Main(args As String())
        '<basic>
        String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
        '</basic>

        Index()
        CompositeFormatDemo()
        Multiple()
        Alignment()
        NowGood()

        Examples_ToString()
        Examples_Currency()
        Examples_Multiple()
        Examples_Bar()
    End Sub

    Sub Index()
        '<index>
        Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                              2, 3, 5, 7)
        Console.WriteLine(primes)

        'The example displays the following output
        '     Four prime numbers 2, 3, 5, 7
        '</index>
    End Sub

    Sub Multiple()
        '<multiple>
        Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                               Int64.MaxValue)
        Console.WriteLine(multiple)

        'The example displays the following output
        '     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
        '</multiple>
    End Sub

    Sub Alignment()
        '<alignment>
        Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                                 "Ebenezer", "Francine", "George"}

        Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                                  40.333D, 80, 16.75D}

        Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

        For counter = 0 To names.Length - 1
            Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
        Next

        'The example displays the following output
        '     Name                 Hours
        '     
        '     Adam                  40.0
        '     Bridgette              6.7
        '     Carla                 40.4
        '     Daniel                82.0
        '     Ebenezer              40.3
        '     Francine              80.0
        '     George                16.8
        '</alignment>
    End Sub

    Sub NowGood()
        '<now_good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}", value)

        Console.WriteLine(output)

        'The example displays the following output
        '      {6324}
        '</now_good>
    End Sub

    Sub Examples_ToString()
        '<example_tostring>
        Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
        Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
        '</example_tostring>
    End Sub

    Sub Examples_Currency()
        '<example_currency>
        Dim myNumber As Integer = 100
        Console.WriteLine("{0:C}", myNumber)

        'The example displays the following output
        'if en-US Is the current culture:
        '       $100.00
        '</example_currency>
    End Sub

    Sub Examples_Multiple()
        '<example_multiple>
        Dim myName As String = "Fred"
        Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                        myName, DateTime.Now))
        'Depending on the current time, the example displays output Like the following:
        '       Name = Fred, hours = 11, minutes = 30
        '</example_multiple>
    End Sub

    Sub Examples_Bar()
        '<example_bar>
        Dim firstName As String = "Fred"
        Dim lastName As String = "Opals"
        Dim myNumber As Integer = 100

        Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
        Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
        Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)
        Console.WriteLine()

        formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
        formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
        formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)

        'The example displays the following output on a system whose current
        'culture Is en-US:
        '    First Name = |      Fred|
        '    Last Name =  |     Opals|
        '    Price =      |   $100.00|
        '
        '    First Name = |Fred      |
        '    Last Name =  |Opals     |
        '    Price =      |$100.00   |
        '</example_bar>
    End Sub

    Sub CompositeFormatDemo()
        '<compositeformat>
        ' Typically stored as a Shared ReadOnly field so it's parsed only once.
        Dim format As CompositeFormat = CompositeFormat.Parse("Name = {0}, hours = {1:hh}")

        ' Pass Nothing for IFormatProvider to use the current culture.
        ' Use the pre-parsed format to avoid reparsing on every call.
        Dim result As String = String.Format(Nothing, format, "Fred", DateTime.Now)
        Console.WriteLine(result)
        ' Output: Name = Fred, hours = 06
        '</compositeformat>
    End Sub

End Module

Format string component

The optional formatString component is a format string that's appropriate for the type of object being formatted. You can specify:

  • A standard or custom numeric format string if the corresponding object is a numeric value.
  • A standard or custom date and time format string if the corresponding object is a System.DateTime object.
  • An enumeration format string if the corresponding object is an enumeration value.

If formatString isn't specified, the general ("G") format specifier for a numeric, date and time, or enumeration type is used. The colon is required if formatString is specified.

The following table lists types or categories of types in the .NET class library that support a predefined set of format strings, and provides links to the articles that list the supported format strings. String formatting is an extensible mechanism that makes it possible to define new format strings for all existing types and to define a set of format strings supported by an application-defined type.

For more information, see the System.IFormattable and System.ICustomFormatter interface articles.

Escaping braces

Opening and closing braces are interpreted as starting and ending a format item. To display a literal opening brace or closing brace, you must use an escape sequence. Specify two opening braces ({{) in the fixed text to display one opening brace ({), or two closing braces (}}) to display one closing brace (}).

Escaped braces with a format item are parsed differently between .NET and .NET Framework.

.NET

Braces can be escaped around a format item. For example, consider the format item {{{0:D}}}, which is intended to display an opening brace, a numeric value formatted as a decimal number, and a closing brace. The format item is interpreted in the following manner:

  1. The first two opening braces ({{) are escaped and yield one opening brace.
  2. The next three characters ({0:) are interpreted as the start of a format item.
  3. The next character (D) is interpreted as the Decimal standard numeric format specifier.
  4. The next brace (}) is interpreted as the end of the format item.
  5. The final two closing braces are escaped and yield one closing brace.
  6. The final result that's displayed is the literal string, {6324}.

sample · csharpdocs/standard/base-types/snippets/composite-formatting/net/csharp/Program.csnow_good

csharp
using System.Text;

void Index()
{
    // <index>
    string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                  2, 3, 5, 7);
    Console.WriteLine(primes);

    // The example displays the following output:
    //      Four prime numbers: 2, 3, 5, 7
    // </index>
}

void Multiple()
{
    // <multiple>
    string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                    Int64.MaxValue);
    Console.WriteLine(multiple);

    // The example displays the following output:
    //      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
    // </multiple>
}

void Alignment()
{
    // <alignment>
    string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                       "Ebenezer", "Francine", "George" };
    decimal[] hours = { 40, 6.667m, 40.39m, 82,
                        40.333m, 80, 16.75m };

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

    for (int counter = 0; counter < names.Length; counter++)
        Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

    // The example displays the following output:
    //      Name                 Hours
    //      
    //      Adam                  40.0
    //      Bridgette              6.7
    //      Carla                 40.4
    //      Daniel                82.0
    //      Ebenezer              40.3
    //      Francine              80.0
    //      George                16.8
    // </alignment>
}

void NowGood()
{
    // <now_good>
    int value = 6324;
    string output = string.Format("{{{0:D}}}", value);
    
    Console.WriteLine(output);
    // The example displays the following output:
    //       {6324}
    // </now_good>
}

void Examples_ToString()
{
    // <example_tostring>
    string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
    string formatString2 = DateTime.Now.ToString("dddd MMMM");
    // </example_tostring>
}

void Examples_Currency()
{
    // <example_currency>
    int myNumber = 100;
    Console.WriteLine($"{myNumber:C}");

    // The example displays the following output
    // if en-US is the current culture:
    //        $100.00
    // </example_currency>
}

void Examples_Multiple()
{
    // <example_multiple>
    string myName = "Fred";
    Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                    myName, DateTime.Now));

    // Depending on the current time, the example displays output like the following:
    //        Name = Fred, hours = 11, minutes = 30
    // </example_multiple>
}

void Examples_Bar()
{
    // <example_bar>
    string firstName = "Fred";
    string lastName = "Opals";
    int myNumber = 100;

    string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
    string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
    string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);
    Console.WriteLine();

    formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
    formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
    formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);

    // The example displays the following output on a system whose current
    // culture is en-US:
    //     First Name = |      Fred|
    //     Last Name =  |     Opals|
    //     Price =      |   $100.00|
    //
    //     First Name = |Fred      |
    //     Last Name =  |Opals     |
    //     Price =      |$100.00   |
    // </example_bar>
}

// <basic>
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
// </basic>

Index();
CompositeFormatDemo();
Multiple();
Alignment();
NowGood();

Examples_ToString();
Examples_Currency();
Examples_Multiple();
Examples_Bar();

void CompositeFormatDemo()
{
    // <compositeformat>
    // Typically stored as a static readonly field so it's parsed only once.
    CompositeFormat format = CompositeFormat.Parse("Name = {0}, hours = {1:hh}");

    // Pass null for IFormatProvider to use the current culture.
    // Use the pre-parsed format to avoid reparsing on every call.
    string result = string.Format(null, format, "Fred", DateTime.Now);
    Console.WriteLine(result);
    // Output: Name = Fred, hours = 06
    // </compositeformat>
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/net/vb/Program.vbnow_good

vb
Imports System
Imports System.Text

Module Program
    Sub Main(args As String())
        '<basic>
        String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
        '</basic>

        Index()
        CompositeFormatDemo()
        Multiple()
        Alignment()
        NowGood()

        Examples_ToString()
        Examples_Currency()
        Examples_Multiple()
        Examples_Bar()
    End Sub

    Sub Index()
        '<index>
        Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                              2, 3, 5, 7)
        Console.WriteLine(primes)

        'The example displays the following output
        '     Four prime numbers 2, 3, 5, 7
        '</index>
    End Sub

    Sub Multiple()
        '<multiple>
        Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                               Int64.MaxValue)
        Console.WriteLine(multiple)

        'The example displays the following output
        '     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
        '</multiple>
    End Sub

    Sub Alignment()
        '<alignment>
        Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                                 "Ebenezer", "Francine", "George"}

        Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                                  40.333D, 80, 16.75D}

        Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

        For counter = 0 To names.Length - 1
            Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
        Next

        'The example displays the following output
        '     Name                 Hours
        '     
        '     Adam                  40.0
        '     Bridgette              6.7
        '     Carla                 40.4
        '     Daniel                82.0
        '     Ebenezer              40.3
        '     Francine              80.0
        '     George                16.8
        '</alignment>
    End Sub

    Sub NowGood()
        '<now_good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}", value)

        Console.WriteLine(output)

        'The example displays the following output
        '      {6324}
        '</now_good>
    End Sub

    Sub Examples_ToString()
        '<example_tostring>
        Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
        Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
        '</example_tostring>
    End Sub

    Sub Examples_Currency()
        '<example_currency>
        Dim myNumber As Integer = 100
        Console.WriteLine("{0:C}", myNumber)

        'The example displays the following output
        'if en-US Is the current culture:
        '       $100.00
        '</example_currency>
    End Sub

    Sub Examples_Multiple()
        '<example_multiple>
        Dim myName As String = "Fred"
        Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                        myName, DateTime.Now))
        'Depending on the current time, the example displays output Like the following:
        '       Name = Fred, hours = 11, minutes = 30
        '</example_multiple>
    End Sub

    Sub Examples_Bar()
        '<example_bar>
        Dim firstName As String = "Fred"
        Dim lastName As String = "Opals"
        Dim myNumber As Integer = 100

        Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
        Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
        Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)
        Console.WriteLine()

        formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
        formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
        formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)

        'The example displays the following output on a system whose current
        'culture Is en-US:
        '    First Name = |      Fred|
        '    Last Name =  |     Opals|
        '    Price =      |   $100.00|
        '
        '    First Name = |Fred      |
        '    Last Name =  |Opals     |
        '    Price =      |$100.00   |
        '</example_bar>
    End Sub

    Sub CompositeFormatDemo()
        '<compositeformat>
        ' Typically stored as a Shared ReadOnly field so it's parsed only once.
        Dim format As CompositeFormat = CompositeFormat.Parse("Name = {0}, hours = {1:hh}")

        ' Pass Nothing for IFormatProvider to use the current culture.
        ' Use the pre-parsed format to avoid reparsing on every call.
        Dim result As String = String.Format(Nothing, format, "Fred", DateTime.Now)
        Console.WriteLine(result)
        ' Output: Name = Fred, hours = 06
        '</compositeformat>
    End Sub

End Module

.NET Framework

Braces in a format item are interpreted sequentially in the order they're encountered. Interpreting nested braces isn't supported.

The way escaped braces are interpreted can lead to unexpected results. For example, consider the format item {{{0:D}}}, which is intended to display an opening brace, a numeric value formatted as a decimal number, and a closing brace. However, the format item is interpreted in the following manner:

  1. The first two opening braces ({{) are escaped and yield one opening brace.
  2. The next three characters ({0:) are interpreted as the start of a format item.
  3. The next character (D) is interpreted as the Decimal standard numeric format specifier, but the next two escaped braces (}}) yield a single brace. Because the resulting string (D}) isn't a standard numeric format specifier, the resulting string is interpreted as a custom format string that means display the literal string D}.
  4. The last brace (}) is interpreted as the end of the format item.
  5. The final result that's displayed is the literal string, {D}. The numeric value that was to be formatted isn't displayed.

sample · csharpdocs/standard/base-types/snippets/composite-formatting/framework/csharp/Program.csbad

csharp
using System;

namespace Formatting
{
    class Program
    {
        static void Main(string[] args)
        {
            Bad();
            Good();
        }

        static void Bad()
        {
            // <bad>
            int value = 6324;
            string output = string.Format("{{{0:D}}}",
                                          value);
            Console.WriteLine(output);

            // The example displays the following output:
            //       {D}
            // </bad>
        }

        static void Good()
        {
            // <good>
            int value = 6324;
            string output = string.Format("{0}{1:D}{2}",
                                         "{", value, "}");
            Console.WriteLine(output);
            
            // The example displays the following output:
            //       {6324}
            // </good>
        }
    }
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/framework/vb/Program.vbbad

vb
Imports System

Module Program
    Sub Main(args As String())
        Bad()
        Good()
    End Sub

    Sub Bad()
        '<bad>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}",
                                             value)
        Console.WriteLine(output)

        'The example displays the following output:
        '      {D}
        '</bad>
    End Sub

    Sub Good()
        '<good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{0}{1:D}{2}",
                                             "{", value, "}")
        Console.WriteLine(output)

        'The example displays the following output:
        '      {6324}
        '</good>
    End Sub

End Module

One way to write your code to avoid misinterpreting escaped braces and format items is to format the braces and format items separately. That is, in the first format operation, display a literal opening brace. In the next operation, display the result of the format item, and in the final operation, display a literal closing brace. The following example illustrates this approach:

sample · csharpdocs/standard/base-types/snippets/composite-formatting/framework/csharp/Program.csgood

csharp
using System;

namespace Formatting
{
    class Program
    {
        static void Main(string[] args)
        {
            Bad();
            Good();
        }

        static void Bad()
        {
            // <bad>
            int value = 6324;
            string output = string.Format("{{{0:D}}}",
                                          value);
            Console.WriteLine(output);

            // The example displays the following output:
            //       {D}
            // </bad>
        }

        static void Good()
        {
            // <good>
            int value = 6324;
            string output = string.Format("{0}{1:D}{2}",
                                         "{", value, "}");
            Console.WriteLine(output);
            
            // The example displays the following output:
            //       {6324}
            // </good>
        }
    }
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/framework/vb/Program.vbgood

vb
Imports System

Module Program
    Sub Main(args As String())
        Bad()
        Good()
    End Sub

    Sub Bad()
        '<bad>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}",
                                             value)
        Console.WriteLine(output)

        'The example displays the following output:
        '      {D}
        '</bad>
    End Sub

    Sub Good()
        '<good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{0}{1:D}{2}",
                                             "{", value, "}")
        Console.WriteLine(output)

        'The example displays the following output:
        '      {6324}
        '</good>
    End Sub

End Module

Processing order

If the call to the composite formatting method includes an System.IFormatProvider argument whose value isn't null, the runtime calls its System.IFormatProvider.GetFormat method to request an System.ICustomFormatter implementation. If the method can return an System.ICustomFormatter implementation, it's cached during the call of the composite formatting method.

Each value in the parameter list that corresponds to a format item is converted to a string as follows:

  1. If the value to be formatted is null, an empty string System.String.Empty is returned.

  2. If an System.ICustomFormatter implementation is available, the runtime calls its System.ICustomFormatter.Format method. The runtime passes the format item's formatString value (or null if it's not present) to the method. The runtime also passes the System.IFormatProvider implementation to the method. If the call to the System.ICustomFormatter.Format method returns null, execution proceeds to the next step. Otherwise, the result of the System.ICustomFormatter.Format call is returned.

  3. If the value implements the System.IFormattable interface, the interface's System.IFormattable.ToString%28System.String%2CSystem.IFormatProvider%29 method is called. If one is present in the format item, the formatString value is passed to the method. Otherwise, null is passed. The System.IFormatProvider argument is determined as follows:

  4. The type's parameterless ToString method, which either overrides System.Object.ToString or inherits the behavior of its base class, is called. In this case, the format string specified by the formatString component in the format item, if it's present, is ignored.

Alignment is applied after the preceding steps have been performed.

Code examples

The following example shows one string created using composite formatting and another created using an object's ToString method. Both types of formatting produce equivalent results.

sample · csharpdocs/standard/base-types/snippets/composite-formatting/net/csharp/Program.csexample_tostring

csharp
using System.Text;

void Index()
{
    // <index>
    string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                  2, 3, 5, 7);
    Console.WriteLine(primes);

    // The example displays the following output:
    //      Four prime numbers: 2, 3, 5, 7
    // </index>
}

void Multiple()
{
    // <multiple>
    string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                    Int64.MaxValue);
    Console.WriteLine(multiple);

    // The example displays the following output:
    //      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
    // </multiple>
}

void Alignment()
{
    // <alignment>
    string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                       "Ebenezer", "Francine", "George" };
    decimal[] hours = { 40, 6.667m, 40.39m, 82,
                        40.333m, 80, 16.75m };

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

    for (int counter = 0; counter < names.Length; counter++)
        Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

    // The example displays the following output:
    //      Name                 Hours
    //      
    //      Adam                  40.0
    //      Bridgette              6.7
    //      Carla                 40.4
    //      Daniel                82.0
    //      Ebenezer              40.3
    //      Francine              80.0
    //      George                16.8
    // </alignment>
}

void NowGood()
{
    // <now_good>
    int value = 6324;
    string output = string.Format("{{{0:D}}}", value);
    
    Console.WriteLine(output);
    // The example displays the following output:
    //       {6324}
    // </now_good>
}

void Examples_ToString()
{
    // <example_tostring>
    string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
    string formatString2 = DateTime.Now.ToString("dddd MMMM");
    // </example_tostring>
}

void Examples_Currency()
{
    // <example_currency>
    int myNumber = 100;
    Console.WriteLine($"{myNumber:C}");

    // The example displays the following output
    // if en-US is the current culture:
    //        $100.00
    // </example_currency>
}

void Examples_Multiple()
{
    // <example_multiple>
    string myName = "Fred";
    Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                    myName, DateTime.Now));

    // Depending on the current time, the example displays output like the following:
    //        Name = Fred, hours = 11, minutes = 30
    // </example_multiple>
}

void Examples_Bar()
{
    // <example_bar>
    string firstName = "Fred";
    string lastName = "Opals";
    int myNumber = 100;

    string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
    string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
    string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);
    Console.WriteLine();

    formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
    formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
    formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);

    // The example displays the following output on a system whose current
    // culture is en-US:
    //     First Name = |      Fred|
    //     Last Name =  |     Opals|
    //     Price =      |   $100.00|
    //
    //     First Name = |Fred      |
    //     Last Name =  |Opals     |
    //     Price =      |$100.00   |
    // </example_bar>
}

// <basic>
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
// </basic>

Index();
CompositeFormatDemo();
Multiple();
Alignment();
NowGood();

Examples_ToString();
Examples_Currency();
Examples_Multiple();
Examples_Bar();

void CompositeFormatDemo()
{
    // <compositeformat>
    // Typically stored as a static readonly field so it's parsed only once.
    CompositeFormat format = CompositeFormat.Parse("Name = {0}, hours = {1:hh}");

    // Pass null for IFormatProvider to use the current culture.
    // Use the pre-parsed format to avoid reparsing on every call.
    string result = string.Format(null, format, "Fred", DateTime.Now);
    Console.WriteLine(result);
    // Output: Name = Fred, hours = 06
    // </compositeformat>
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/net/vb/Program.vbexample_tostring

vb
Imports System
Imports System.Text

Module Program
    Sub Main(args As String())
        '<basic>
        String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
        '</basic>

        Index()
        CompositeFormatDemo()
        Multiple()
        Alignment()
        NowGood()

        Examples_ToString()
        Examples_Currency()
        Examples_Multiple()
        Examples_Bar()
    End Sub

    Sub Index()
        '<index>
        Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                              2, 3, 5, 7)
        Console.WriteLine(primes)

        'The example displays the following output
        '     Four prime numbers 2, 3, 5, 7
        '</index>
    End Sub

    Sub Multiple()
        '<multiple>
        Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                               Int64.MaxValue)
        Console.WriteLine(multiple)

        'The example displays the following output
        '     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
        '</multiple>
    End Sub

    Sub Alignment()
        '<alignment>
        Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                                 "Ebenezer", "Francine", "George"}

        Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                                  40.333D, 80, 16.75D}

        Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

        For counter = 0 To names.Length - 1
            Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
        Next

        'The example displays the following output
        '     Name                 Hours
        '     
        '     Adam                  40.0
        '     Bridgette              6.7
        '     Carla                 40.4
        '     Daniel                82.0
        '     Ebenezer              40.3
        '     Francine              80.0
        '     George                16.8
        '</alignment>
    End Sub

    Sub NowGood()
        '<now_good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}", value)

        Console.WriteLine(output)

        'The example displays the following output
        '      {6324}
        '</now_good>
    End Sub

    Sub Examples_ToString()
        '<example_tostring>
        Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
        Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
        '</example_tostring>
    End Sub

    Sub Examples_Currency()
        '<example_currency>
        Dim myNumber As Integer = 100
        Console.WriteLine("{0:C}", myNumber)

        'The example displays the following output
        'if en-US Is the current culture:
        '       $100.00
        '</example_currency>
    End Sub

    Sub Examples_Multiple()
        '<example_multiple>
        Dim myName As String = "Fred"
        Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                        myName, DateTime.Now))
        'Depending on the current time, the example displays output Like the following:
        '       Name = Fred, hours = 11, minutes = 30
        '</example_multiple>
    End Sub

    Sub Examples_Bar()
        '<example_bar>
        Dim firstName As String = "Fred"
        Dim lastName As String = "Opals"
        Dim myNumber As Integer = 100

        Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
        Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
        Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)
        Console.WriteLine()

        formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
        formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
        formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)

        'The example displays the following output on a system whose current
        'culture Is en-US:
        '    First Name = |      Fred|
        '    Last Name =  |     Opals|
        '    Price =      |   $100.00|
        '
        '    First Name = |Fred      |
        '    Last Name =  |Opals     |
        '    Price =      |$100.00   |
        '</example_bar>
    End Sub

    Sub CompositeFormatDemo()
        '<compositeformat>
        ' Typically stored as a Shared ReadOnly field so it's parsed only once.
        Dim format As CompositeFormat = CompositeFormat.Parse("Name = {0}, hours = {1:hh}")

        ' Pass Nothing for IFormatProvider to use the current culture.
        ' Use the pre-parsed format to avoid reparsing on every call.
        Dim result As String = String.Format(Nothing, format, "Fred", DateTime.Now)
        Console.WriteLine(result)
        ' Output: Name = Fred, hours = 06
        '</compositeformat>
    End Sub

End Module

Assuming that the current day is a Thursday in May, the value of both strings in the preceding example is Thursday May in the U.S. English culture.

System.Console.WriteLine exposes the same functionality as System.String.Format. The only difference between the two methods is that System.String.Format returns its result as a string, while System.Console.WriteLine writes the result to the output stream associated with the System.Console object. The following example uses the System.Console.WriteLine method to format the value of myNumber to a currency value:

sample · csharpdocs/standard/base-types/snippets/composite-formatting/net/csharp/Program.csexample_currency

csharp
using System.Text;

void Index()
{
    // <index>
    string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                  2, 3, 5, 7);
    Console.WriteLine(primes);

    // The example displays the following output:
    //      Four prime numbers: 2, 3, 5, 7
    // </index>
}

void Multiple()
{
    // <multiple>
    string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                    Int64.MaxValue);
    Console.WriteLine(multiple);

    // The example displays the following output:
    //      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
    // </multiple>
}

void Alignment()
{
    // <alignment>
    string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                       "Ebenezer", "Francine", "George" };
    decimal[] hours = { 40, 6.667m, 40.39m, 82,
                        40.333m, 80, 16.75m };

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

    for (int counter = 0; counter < names.Length; counter++)
        Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

    // The example displays the following output:
    //      Name                 Hours
    //      
    //      Adam                  40.0
    //      Bridgette              6.7
    //      Carla                 40.4
    //      Daniel                82.0
    //      Ebenezer              40.3
    //      Francine              80.0
    //      George                16.8
    // </alignment>
}

void NowGood()
{
    // <now_good>
    int value = 6324;
    string output = string.Format("{{{0:D}}}", value);
    
    Console.WriteLine(output);
    // The example displays the following output:
    //       {6324}
    // </now_good>
}

void Examples_ToString()
{
    // <example_tostring>
    string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
    string formatString2 = DateTime.Now.ToString("dddd MMMM");
    // </example_tostring>
}

void Examples_Currency()
{
    // <example_currency>
    int myNumber = 100;
    Console.WriteLine($"{myNumber:C}");

    // The example displays the following output
    // if en-US is the current culture:
    //        $100.00
    // </example_currency>
}

void Examples_Multiple()
{
    // <example_multiple>
    string myName = "Fred";
    Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                    myName, DateTime.Now));

    // Depending on the current time, the example displays output like the following:
    //        Name = Fred, hours = 11, minutes = 30
    // </example_multiple>
}

void Examples_Bar()
{
    // <example_bar>
    string firstName = "Fred";
    string lastName = "Opals";
    int myNumber = 100;

    string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
    string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
    string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);
    Console.WriteLine();

    formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
    formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
    formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);

    // The example displays the following output on a system whose current
    // culture is en-US:
    //     First Name = |      Fred|
    //     Last Name =  |     Opals|
    //     Price =      |   $100.00|
    //
    //     First Name = |Fred      |
    //     Last Name =  |Opals     |
    //     Price =      |$100.00   |
    // </example_bar>
}

// <basic>
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
// </basic>

Index();
CompositeFormatDemo();
Multiple();
Alignment();
NowGood();

Examples_ToString();
Examples_Currency();
Examples_Multiple();
Examples_Bar();

void CompositeFormatDemo()
{
    // <compositeformat>
    // Typically stored as a static readonly field so it's parsed only once.
    CompositeFormat format = CompositeFormat.Parse("Name = {0}, hours = {1:hh}");

    // Pass null for IFormatProvider to use the current culture.
    // Use the pre-parsed format to avoid reparsing on every call.
    string result = string.Format(null, format, "Fred", DateTime.Now);
    Console.WriteLine(result);
    // Output: Name = Fred, hours = 06
    // </compositeformat>
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/net/vb/Program.vbexample_currency

vb
Imports System
Imports System.Text

Module Program
    Sub Main(args As String())
        '<basic>
        String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
        '</basic>

        Index()
        CompositeFormatDemo()
        Multiple()
        Alignment()
        NowGood()

        Examples_ToString()
        Examples_Currency()
        Examples_Multiple()
        Examples_Bar()
    End Sub

    Sub Index()
        '<index>
        Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                              2, 3, 5, 7)
        Console.WriteLine(primes)

        'The example displays the following output
        '     Four prime numbers 2, 3, 5, 7
        '</index>
    End Sub

    Sub Multiple()
        '<multiple>
        Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                               Int64.MaxValue)
        Console.WriteLine(multiple)

        'The example displays the following output
        '     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
        '</multiple>
    End Sub

    Sub Alignment()
        '<alignment>
        Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                                 "Ebenezer", "Francine", "George"}

        Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                                  40.333D, 80, 16.75D}

        Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

        For counter = 0 To names.Length - 1
            Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
        Next

        'The example displays the following output
        '     Name                 Hours
        '     
        '     Adam                  40.0
        '     Bridgette              6.7
        '     Carla                 40.4
        '     Daniel                82.0
        '     Ebenezer              40.3
        '     Francine              80.0
        '     George                16.8
        '</alignment>
    End Sub

    Sub NowGood()
        '<now_good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}", value)

        Console.WriteLine(output)

        'The example displays the following output
        '      {6324}
        '</now_good>
    End Sub

    Sub Examples_ToString()
        '<example_tostring>
        Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
        Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
        '</example_tostring>
    End Sub

    Sub Examples_Currency()
        '<example_currency>
        Dim myNumber As Integer = 100
        Console.WriteLine("{0:C}", myNumber)

        'The example displays the following output
        'if en-US Is the current culture:
        '       $100.00
        '</example_currency>
    End Sub

    Sub Examples_Multiple()
        '<example_multiple>
        Dim myName As String = "Fred"
        Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                        myName, DateTime.Now))
        'Depending on the current time, the example displays output Like the following:
        '       Name = Fred, hours = 11, minutes = 30
        '</example_multiple>
    End Sub

    Sub Examples_Bar()
        '<example_bar>
        Dim firstName As String = "Fred"
        Dim lastName As String = "Opals"
        Dim myNumber As Integer = 100

        Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
        Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
        Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)
        Console.WriteLine()

        formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
        formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
        formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)

        'The example displays the following output on a system whose current
        'culture Is en-US:
        '    First Name = |      Fred|
        '    Last Name =  |     Opals|
        '    Price =      |   $100.00|
        '
        '    First Name = |Fred      |
        '    Last Name =  |Opals     |
        '    Price =      |$100.00   |
        '</example_bar>
    End Sub

    Sub CompositeFormatDemo()
        '<compositeformat>
        ' Typically stored as a Shared ReadOnly field so it's parsed only once.
        Dim format As CompositeFormat = CompositeFormat.Parse("Name = {0}, hours = {1:hh}")

        ' Pass Nothing for IFormatProvider to use the current culture.
        ' Use the pre-parsed format to avoid reparsing on every call.
        Dim result As String = String.Format(Nothing, format, "Fred", DateTime.Now)
        Console.WriteLine(result)
        ' Output: Name = Fred, hours = 06
        '</compositeformat>
    End Sub

End Module

The following example demonstrates formatting multiple objects, including formatting one object in two different ways:

sample · csharpdocs/standard/base-types/snippets/composite-formatting/net/csharp/Program.csexample_multiple

csharp
using System.Text;

void Index()
{
    // <index>
    string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                  2, 3, 5, 7);
    Console.WriteLine(primes);

    // The example displays the following output:
    //      Four prime numbers: 2, 3, 5, 7
    // </index>
}

void Multiple()
{
    // <multiple>
    string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                    Int64.MaxValue);
    Console.WriteLine(multiple);

    // The example displays the following output:
    //      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
    // </multiple>
}

void Alignment()
{
    // <alignment>
    string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                       "Ebenezer", "Francine", "George" };
    decimal[] hours = { 40, 6.667m, 40.39m, 82,
                        40.333m, 80, 16.75m };

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

    for (int counter = 0; counter < names.Length; counter++)
        Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

    // The example displays the following output:
    //      Name                 Hours
    //      
    //      Adam                  40.0
    //      Bridgette              6.7
    //      Carla                 40.4
    //      Daniel                82.0
    //      Ebenezer              40.3
    //      Francine              80.0
    //      George                16.8
    // </alignment>
}

void NowGood()
{
    // <now_good>
    int value = 6324;
    string output = string.Format("{{{0:D}}}", value);
    
    Console.WriteLine(output);
    // The example displays the following output:
    //       {6324}
    // </now_good>
}

void Examples_ToString()
{
    // <example_tostring>
    string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
    string formatString2 = DateTime.Now.ToString("dddd MMMM");
    // </example_tostring>
}

void Examples_Currency()
{
    // <example_currency>
    int myNumber = 100;
    Console.WriteLine($"{myNumber:C}");

    // The example displays the following output
    // if en-US is the current culture:
    //        $100.00
    // </example_currency>
}

void Examples_Multiple()
{
    // <example_multiple>
    string myName = "Fred";
    Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                    myName, DateTime.Now));

    // Depending on the current time, the example displays output like the following:
    //        Name = Fred, hours = 11, minutes = 30
    // </example_multiple>
}

void Examples_Bar()
{
    // <example_bar>
    string firstName = "Fred";
    string lastName = "Opals";
    int myNumber = 100;

    string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
    string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
    string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);
    Console.WriteLine();

    formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
    formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
    formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);

    // The example displays the following output on a system whose current
    // culture is en-US:
    //     First Name = |      Fred|
    //     Last Name =  |     Opals|
    //     Price =      |   $100.00|
    //
    //     First Name = |Fred      |
    //     Last Name =  |Opals     |
    //     Price =      |$100.00   |
    // </example_bar>
}

// <basic>
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
// </basic>

Index();
CompositeFormatDemo();
Multiple();
Alignment();
NowGood();

Examples_ToString();
Examples_Currency();
Examples_Multiple();
Examples_Bar();

void CompositeFormatDemo()
{
    // <compositeformat>
    // Typically stored as a static readonly field so it's parsed only once.
    CompositeFormat format = CompositeFormat.Parse("Name = {0}, hours = {1:hh}");

    // Pass null for IFormatProvider to use the current culture.
    // Use the pre-parsed format to avoid reparsing on every call.
    string result = string.Format(null, format, "Fred", DateTime.Now);
    Console.WriteLine(result);
    // Output: Name = Fred, hours = 06
    // </compositeformat>
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/net/vb/Program.vbexample_multiple

vb
Imports System
Imports System.Text

Module Program
    Sub Main(args As String())
        '<basic>
        String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
        '</basic>

        Index()
        CompositeFormatDemo()
        Multiple()
        Alignment()
        NowGood()

        Examples_ToString()
        Examples_Currency()
        Examples_Multiple()
        Examples_Bar()
    End Sub

    Sub Index()
        '<index>
        Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                              2, 3, 5, 7)
        Console.WriteLine(primes)

        'The example displays the following output
        '     Four prime numbers 2, 3, 5, 7
        '</index>
    End Sub

    Sub Multiple()
        '<multiple>
        Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                               Int64.MaxValue)
        Console.WriteLine(multiple)

        'The example displays the following output
        '     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
        '</multiple>
    End Sub

    Sub Alignment()
        '<alignment>
        Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                                 "Ebenezer", "Francine", "George"}

        Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                                  40.333D, 80, 16.75D}

        Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

        For counter = 0 To names.Length - 1
            Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
        Next

        'The example displays the following output
        '     Name                 Hours
        '     
        '     Adam                  40.0
        '     Bridgette              6.7
        '     Carla                 40.4
        '     Daniel                82.0
        '     Ebenezer              40.3
        '     Francine              80.0
        '     George                16.8
        '</alignment>
    End Sub

    Sub NowGood()
        '<now_good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}", value)

        Console.WriteLine(output)

        'The example displays the following output
        '      {6324}
        '</now_good>
    End Sub

    Sub Examples_ToString()
        '<example_tostring>
        Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
        Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
        '</example_tostring>
    End Sub

    Sub Examples_Currency()
        '<example_currency>
        Dim myNumber As Integer = 100
        Console.WriteLine("{0:C}", myNumber)

        'The example displays the following output
        'if en-US Is the current culture:
        '       $100.00
        '</example_currency>
    End Sub

    Sub Examples_Multiple()
        '<example_multiple>
        Dim myName As String = "Fred"
        Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                        myName, DateTime.Now))
        'Depending on the current time, the example displays output Like the following:
        '       Name = Fred, hours = 11, minutes = 30
        '</example_multiple>
    End Sub

    Sub Examples_Bar()
        '<example_bar>
        Dim firstName As String = "Fred"
        Dim lastName As String = "Opals"
        Dim myNumber As Integer = 100

        Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
        Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
        Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)
        Console.WriteLine()

        formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
        formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
        formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)

        'The example displays the following output on a system whose current
        'culture Is en-US:
        '    First Name = |      Fred|
        '    Last Name =  |     Opals|
        '    Price =      |   $100.00|
        '
        '    First Name = |Fred      |
        '    Last Name =  |Opals     |
        '    Price =      |$100.00   |
        '</example_bar>
    End Sub

    Sub CompositeFormatDemo()
        '<compositeformat>
        ' Typically stored as a Shared ReadOnly field so it's parsed only once.
        Dim format As CompositeFormat = CompositeFormat.Parse("Name = {0}, hours = {1:hh}")

        ' Pass Nothing for IFormatProvider to use the current culture.
        ' Use the pre-parsed format to avoid reparsing on every call.
        Dim result As String = String.Format(Nothing, format, "Fred", DateTime.Now)
        Console.WriteLine(result)
        ' Output: Name = Fred, hours = 06
        '</compositeformat>
    End Sub

End Module

The following example demonstrates the use of width in formatting. The arguments that are formatted are placed between vertical bar characters (|) to highlight the resulting alignment.

sample · csharpdocs/standard/base-types/snippets/composite-formatting/net/csharp/Program.csexample_bar

csharp
using System.Text;

void Index()
{
    // <index>
    string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                  2, 3, 5, 7);
    Console.WriteLine(primes);

    // The example displays the following output:
    //      Four prime numbers: 2, 3, 5, 7
    // </index>
}

void Multiple()
{
    // <multiple>
    string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                    Int64.MaxValue);
    Console.WriteLine(multiple);

    // The example displays the following output:
    //      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
    // </multiple>
}

void Alignment()
{
    // <alignment>
    string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                       "Ebenezer", "Francine", "George" };
    decimal[] hours = { 40, 6.667m, 40.39m, 82,
                        40.333m, 80, 16.75m };

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

    for (int counter = 0; counter < names.Length; counter++)
        Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

    // The example displays the following output:
    //      Name                 Hours
    //      
    //      Adam                  40.0
    //      Bridgette              6.7
    //      Carla                 40.4
    //      Daniel                82.0
    //      Ebenezer              40.3
    //      Francine              80.0
    //      George                16.8
    // </alignment>
}

void NowGood()
{
    // <now_good>
    int value = 6324;
    string output = string.Format("{{{0:D}}}", value);
    
    Console.WriteLine(output);
    // The example displays the following output:
    //       {6324}
    // </now_good>
}

void Examples_ToString()
{
    // <example_tostring>
    string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
    string formatString2 = DateTime.Now.ToString("dddd MMMM");
    // </example_tostring>
}

void Examples_Currency()
{
    // <example_currency>
    int myNumber = 100;
    Console.WriteLine($"{myNumber:C}");

    // The example displays the following output
    // if en-US is the current culture:
    //        $100.00
    // </example_currency>
}

void Examples_Multiple()
{
    // <example_multiple>
    string myName = "Fred";
    Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                    myName, DateTime.Now));

    // Depending on the current time, the example displays output like the following:
    //        Name = Fred, hours = 11, minutes = 30
    // </example_multiple>
}

void Examples_Bar()
{
    // <example_bar>
    string firstName = "Fred";
    string lastName = "Opals";
    int myNumber = 100;

    string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
    string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
    string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);
    Console.WriteLine();

    formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
    formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
    formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);

    // The example displays the following output on a system whose current
    // culture is en-US:
    //     First Name = |      Fred|
    //     Last Name =  |     Opals|
    //     Price =      |   $100.00|
    //
    //     First Name = |Fred      |
    //     Last Name =  |Opals     |
    //     Price =      |$100.00   |
    // </example_bar>
}

// <basic>
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
// </basic>

Index();
CompositeFormatDemo();
Multiple();
Alignment();
NowGood();

Examples_ToString();
Examples_Currency();
Examples_Multiple();
Examples_Bar();

void CompositeFormatDemo()
{
    // <compositeformat>
    // Typically stored as a static readonly field so it's parsed only once.
    CompositeFormat format = CompositeFormat.Parse("Name = {0}, hours = {1:hh}");

    // Pass null for IFormatProvider to use the current culture.
    // Use the pre-parsed format to avoid reparsing on every call.
    string result = string.Format(null, format, "Fred", DateTime.Now);
    Console.WriteLine(result);
    // Output: Name = Fred, hours = 06
    // </compositeformat>
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/net/vb/Program.vbexample_bar

vb
Imports System
Imports System.Text

Module Program
    Sub Main(args As String())
        '<basic>
        String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
        '</basic>

        Index()
        CompositeFormatDemo()
        Multiple()
        Alignment()
        NowGood()

        Examples_ToString()
        Examples_Currency()
        Examples_Multiple()
        Examples_Bar()
    End Sub

    Sub Index()
        '<index>
        Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                              2, 3, 5, 7)
        Console.WriteLine(primes)

        'The example displays the following output
        '     Four prime numbers 2, 3, 5, 7
        '</index>
    End Sub

    Sub Multiple()
        '<multiple>
        Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                               Int64.MaxValue)
        Console.WriteLine(multiple)

        'The example displays the following output
        '     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
        '</multiple>
    End Sub

    Sub Alignment()
        '<alignment>
        Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                                 "Ebenezer", "Francine", "George"}

        Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                                  40.333D, 80, 16.75D}

        Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

        For counter = 0 To names.Length - 1
            Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
        Next

        'The example displays the following output
        '     Name                 Hours
        '     
        '     Adam                  40.0
        '     Bridgette              6.7
        '     Carla                 40.4
        '     Daniel                82.0
        '     Ebenezer              40.3
        '     Francine              80.0
        '     George                16.8
        '</alignment>
    End Sub

    Sub NowGood()
        '<now_good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}", value)

        Console.WriteLine(output)

        'The example displays the following output
        '      {6324}
        '</now_good>
    End Sub

    Sub Examples_ToString()
        '<example_tostring>
        Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
        Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
        '</example_tostring>
    End Sub

    Sub Examples_Currency()
        '<example_currency>
        Dim myNumber As Integer = 100
        Console.WriteLine("{0:C}", myNumber)

        'The example displays the following output
        'if en-US Is the current culture:
        '       $100.00
        '</example_currency>
    End Sub

    Sub Examples_Multiple()
        '<example_multiple>
        Dim myName As String = "Fred"
        Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                        myName, DateTime.Now))
        'Depending on the current time, the example displays output Like the following:
        '       Name = Fred, hours = 11, minutes = 30
        '</example_multiple>
    End Sub

    Sub Examples_Bar()
        '<example_bar>
        Dim firstName As String = "Fred"
        Dim lastName As String = "Opals"
        Dim myNumber As Integer = 100

        Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
        Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
        Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)
        Console.WriteLine()

        formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
        formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
        formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)

        'The example displays the following output on a system whose current
        'culture Is en-US:
        '    First Name = |      Fred|
        '    Last Name =  |     Opals|
        '    Price =      |   $100.00|
        '
        '    First Name = |Fred      |
        '    Last Name =  |Opals     |
        '    Price =      |$100.00   |
        '</example_bar>
    End Sub

    Sub CompositeFormatDemo()
        '<compositeformat>
        ' Typically stored as a Shared ReadOnly field so it's parsed only once.
        Dim format As CompositeFormat = CompositeFormat.Parse("Name = {0}, hours = {1:hh}")

        ' Pass Nothing for IFormatProvider to use the current culture.
        ' Use the pre-parsed format to avoid reparsing on every call.
        Dim result As String = String.Format(Nothing, format, "Fred", DateTime.Now)
        Console.WriteLine(result)
        ' Output: Name = Fred, hours = 06
        '</compositeformat>
    End Sub

End Module

Improve performance with CompositeFormat

Starting with .NET 8, use the System.Text.CompositeFormat class to improve the performance of composite string formatting when the same format string is used repeatedly. Parsing a composite format string at runtime is expensive, and System.Text.CompositeFormat pre-parses it once when you create the instance, so the formatting code in your performance-critical code path can run much faster.

To use CompositeFormat:

  1. Call System.Text.CompositeFormat.Parse(System.String) to create a CompositeFormat instance. For best results, cache this instance—typically as a static readonly field in C# or a Shared ReadOnly field in Visual Basic—so the format string is parsed only once.
  2. Pass the cached instance to System.String.Format or System.Text.StringBuilder.AppendFormat instead of the original format string.

sample · csharpdocs/standard/base-types/snippets/composite-formatting/net/csharp/Program.cscompositeformat

csharp
using System.Text;

void Index()
{
    // <index>
    string primes = string.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                  2, 3, 5, 7);
    Console.WriteLine(primes);

    // The example displays the following output:
    //      Four prime numbers: 2, 3, 5, 7
    // </index>
}

void Multiple()
{
    // <multiple>
    string multiple = string.Format("0x{0:X} {0:E} {0:N}",
                                    Int64.MaxValue);
    Console.WriteLine(multiple);

    // The example displays the following output:
    //      0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
    // </multiple>
}

void Alignment()
{
    // <alignment>
    string[] names = { "Adam", "Bridgette", "Carla", "Daniel",
                       "Ebenezer", "Francine", "George" };
    decimal[] hours = { 40, 6.667m, 40.39m, 82,
                        40.333m, 80, 16.75m };

    Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours");

    for (int counter = 0; counter < names.Length; counter++)
        Console.WriteLine("{0,-20} {1,5:N1}", names[counter], hours[counter]);

    // The example displays the following output:
    //      Name                 Hours
    //      
    //      Adam                  40.0
    //      Bridgette              6.7
    //      Carla                 40.4
    //      Daniel                82.0
    //      Ebenezer              40.3
    //      Francine              80.0
    //      George                16.8
    // </alignment>
}

void NowGood()
{
    // <now_good>
    int value = 6324;
    string output = string.Format("{{{0:D}}}", value);
    
    Console.WriteLine(output);
    // The example displays the following output:
    //       {6324}
    // </now_good>
}

void Examples_ToString()
{
    // <example_tostring>
    string formatString1 = string.Format("{0:dddd MMMM}", DateTime.Now);
    string formatString2 = DateTime.Now.ToString("dddd MMMM");
    // </example_tostring>
}

void Examples_Currency()
{
    // <example_currency>
    int myNumber = 100;
    Console.WriteLine($"{myNumber:C}");

    // The example displays the following output
    // if en-US is the current culture:
    //        $100.00
    // </example_currency>
}

void Examples_Multiple()
{
    // <example_multiple>
    string myName = "Fred";
    Console.WriteLine(string.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                    myName, DateTime.Now));

    // Depending on the current time, the example displays output like the following:
    //        Name = Fred, hours = 11, minutes = 30
    // </example_multiple>
}

void Examples_Bar()
{
    // <example_bar>
    string firstName = "Fred";
    string lastName = "Opals";
    int myNumber = 100;

    string formatFirstName = string.Format("First Name = |{0,10}|", firstName);
    string formatLastName = string.Format("Last Name =  |{0,10}|", lastName);
    string formatPrice = string.Format("Price =      |{0,10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);
    Console.WriteLine();

    formatFirstName = string.Format("First Name = |{0,-10}|", firstName);
    formatLastName = string.Format("Last Name =  |{0,-10}|", lastName);
    formatPrice = string.Format("Price =      |{0,-10:C}|", myNumber);
    Console.WriteLine(formatFirstName);
    Console.WriteLine(formatLastName);
    Console.WriteLine(formatPrice);

    // The example displays the following output on a system whose current
    // culture is en-US:
    //     First Name = |      Fred|
    //     Last Name =  |     Opals|
    //     Price =      |   $100.00|
    //
    //     First Name = |Fred      |
    //     Last Name =  |Opals     |
    //     Price =      |$100.00   |
    // </example_bar>
}

// <basic>
string.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now);
// </basic>

Index();
CompositeFormatDemo();
Multiple();
Alignment();
NowGood();

Examples_ToString();
Examples_Currency();
Examples_Multiple();
Examples_Bar();

void CompositeFormatDemo()
{
    // <compositeformat>
    // Typically stored as a static readonly field so it's parsed only once.
    CompositeFormat format = CompositeFormat.Parse("Name = {0}, hours = {1:hh}");

    // Pass null for IFormatProvider to use the current culture.
    // Use the pre-parsed format to avoid reparsing on every call.
    string result = string.Format(null, format, "Fred", DateTime.Now);
    Console.WriteLine(result);
    // Output: Name = Fred, hours = 06
    // </compositeformat>
}

sample · vbdocs/standard/base-types/snippets/composite-formatting/net/vb/Program.vbcompositeformat

vb
Imports System
Imports System.Text

Module Program
    Sub Main(args As String())
        '<basic>
        String.Format("Name = {0}, hours = {1:hh}", "Fred", DateTime.Now)
        '</basic>

        Index()
        CompositeFormatDemo()
        Multiple()
        Alignment()
        NowGood()

        Examples_ToString()
        Examples_Currency()
        Examples_Multiple()
        Examples_Bar()
    End Sub

    Sub Index()
        '<index>
        Dim primes As String = String.Format("Four prime numbers: {0}, {1}, {2}, {3}",
                                              2, 3, 5, 7)
        Console.WriteLine(primes)

        'The example displays the following output
        '     Four prime numbers 2, 3, 5, 7
        '</index>
    End Sub

    Sub Multiple()
        '<multiple>
        Dim multiple As String = String.Format("0x{0:X} {0:E} {0:N}",
                                               Int64.MaxValue)
        Console.WriteLine(multiple)

        'The example displays the following output
        '     0x7FFFFFFFFFFFFFFF 9.223372E+018 9,223,372,036,854,775,807.00
        '</multiple>
    End Sub

    Sub Alignment()
        '<alignment>
        Dim names As String() = {"Adam", "Bridgette", "Carla", "Daniel",
                                 "Ebenezer", "Francine", "George"}

        Dim hours As Decimal() = {40, 6.667D, 40.39D, 82,
                                  40.333D, 80, 16.75D}

        Console.WriteLine("{0,-20} {1,5}\n", "Name", "Hours")

        For counter = 0 To names.Length - 1
            Console.WriteLine("{0,-20} {1,5:N1}", names(counter), hours(counter))
        Next

        'The example displays the following output
        '     Name                 Hours
        '     
        '     Adam                  40.0
        '     Bridgette              6.7
        '     Carla                 40.4
        '     Daniel                82.0
        '     Ebenezer              40.3
        '     Francine              80.0
        '     George                16.8
        '</alignment>
    End Sub

    Sub NowGood()
        '<now_good>
        Dim value As Integer = 6324
        Dim output As String = String.Format("{{{0:D}}}", value)

        Console.WriteLine(output)

        'The example displays the following output
        '      {6324}
        '</now_good>
    End Sub

    Sub Examples_ToString()
        '<example_tostring>
        Dim formatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
        Dim formatString2 As String = DateTime.Now.ToString("dddd MMMM")
        '</example_tostring>
    End Sub

    Sub Examples_Currency()
        '<example_currency>
        Dim myNumber As Integer = 100
        Console.WriteLine("{0:C}", myNumber)

        'The example displays the following output
        'if en-US Is the current culture:
        '       $100.00
        '</example_currency>
    End Sub

    Sub Examples_Multiple()
        '<example_multiple>
        Dim myName As String = "Fred"
        Console.WriteLine(String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
                                        myName, DateTime.Now))
        'Depending on the current time, the example displays output Like the following:
        '       Name = Fred, hours = 11, minutes = 30
        '</example_multiple>
    End Sub

    Sub Examples_Bar()
        '<example_bar>
        Dim firstName As String = "Fred"
        Dim lastName As String = "Opals"
        Dim myNumber As Integer = 100

        Dim formatFirstName As String = String.Format("First Name = |{0,10}|", firstName)
        Dim formatLastName As String = String.Format("Last Name =  |{0,10}|", lastName)
        Dim formatPrice As String = String.Format("Price =      |{0,10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)
        Console.WriteLine()

        formatFirstName = String.Format("First Name = |{0,-10}|", firstName)
        formatLastName = String.Format("Last Name =  |{0,-10}|", lastName)
        formatPrice = String.Format("Price =      |{0,-10:C}|", myNumber)
        Console.WriteLine(formatFirstName)
        Console.WriteLine(formatLastName)
        Console.WriteLine(formatPrice)

        'The example displays the following output on a system whose current
        'culture Is en-US:
        '    First Name = |      Fred|
        '    Last Name =  |     Opals|
        '    Price =      |   $100.00|
        '
        '    First Name = |Fred      |
        '    Last Name =  |Opals     |
        '    Price =      |$100.00   |
        '</example_bar>
    End Sub

    Sub CompositeFormatDemo()
        '<compositeformat>
        ' Typically stored as a Shared ReadOnly field so it's parsed only once.
        Dim format As CompositeFormat = CompositeFormat.Parse("Name = {0}, hours = {1:hh}")

        ' Pass Nothing for IFormatProvider to use the current culture.
        ' Use the pre-parsed format to avoid reparsing on every call.
        Dim result As String = String.Format(Nothing, format, "Fred", DateTime.Now)
        Console.WriteLine(result)
        ' Output: Name = Fred, hours = 06
        '</compositeformat>
    End Sub

End Module

The CA1863 code analyzer rule detects places in your code where you can use CompositeFormat to improve performance.

See also