String interpolation in C#

This tutorial shows you how to use string interpolation to format and include expression results in a result string. The examples assume that you are familiar with basic C# concepts and .NET type formatting. If you are new to string interpolation or .NET type formatting, check out the interactive string interpolation tutorial first. For more information about formatting types in .NET, see the Formatting Types in .NET topic.

Note

The C# examples in this article run in the Try.NET inline code runner and playground. Select the Run button to run an example in an interactive window. Once you execute the code, you can modify it and run the modified code by selecting Run again. The modified code either runs in the interactive window or, if compilation fails, the interactive window displays all C# compiler error messages.

Introduction

The string interpolation feature is built on top of the composite formatting feature and provides a more readable and convenient syntax to include formatted expression results in a result string.

To identify a string literal as an interpolated string, prepend it with the $ symbol. You can embed any valid C# expression that returns a value in an interpolated string. In the following example, as soon as an expression is evaluated, its result is converted into a string and included in a result string:

double a = 3;
double b = 4;
Console.WriteLine($"Area of the right triangle with legs of {a} and {b} is {0.5 * a * b}");
Console.WriteLine($"Length of the hypotenuse of the right triangle with legs of {a} and {b} is {CalculateHypotenuse(a, b)}");

double CalculateHypotenuse(double leg1, double leg2) => Math.Sqrt(leg1 * leg1 + leg2 * leg2);

// Expected output:
// Area of the right triangle with legs of 3 and 4 is 6
// Length of the hypotenuse of the right triangle with legs of 3 and 4 is 5

As the example shows, you include an expression in an interpolated string by enclosing it with braces:

{<interpolatedExpression>}

At compile time, an interpolated string is typically transformed into a String.Format method call. That makes all the capabilities of the string composite formatting feature available to you to use with interpolated strings as well.

The compiler may substitute a String.Format for String.Concat if the analyzed behavior would be equivalent to concatenation.

How to specify a format string for an interpolated expression

You specify a format string that is supported by the type of the expression result by following the interpolated expression with a colon (":") and the format string:

{<interpolatedExpression>:<formatString>}

The following example shows how to specify standard and custom format strings for expressions that produce date and time or numeric results:

var date = new DateTime(1731, 11, 25);
Console.WriteLine($"On {date:dddd, MMMM dd, yyyy} Leonhard Euler introduced the letter e to denote {Math.E:F5} in a letter to Christian Goldbach.");

// Expected output:
// On Sunday, November 25, 1731 Leonhard Euler introduced the letter e to denote 2.71828 in a letter to Christian Goldbach.

For more information, see the Format String Component section of the Composite Formatting topic. That section provides links to the topics that describe standard and custom format strings supported by .NET base types.

How to control the field width and alignment of the formatted interpolated expression

You specify the minimum field width and the alignment of the formatted expression result by following the interpolated expression with a comma (",") and the constant expression:

{<interpolatedExpression>,<alignment>}

If the alignment value is positive, the formatted expression result is right-aligned; if negative, it's left-aligned.

If you need to specify both alignment and a format string, start with the alignment component:

{<interpolatedExpression>,<alignment>:<formatString>}

The following example shows how to specify alignment and uses pipe characters ("|") to delimit text fields:

const int NameAlignment = -9;
const int ValueAlignment = 7;

double a = 3;
double b = 4;
Console.WriteLine($"Three classical Pythagorean means of {a} and {b}:");
Console.WriteLine($"|{"Arithmetic",NameAlignment}|{0.5 * (a + b),ValueAlignment:F3}|");
Console.WriteLine($"|{"Geometric",NameAlignment}|{Math.Sqrt(a * b),ValueAlignment:F3}|");
Console.WriteLine($"|{"Harmonic",NameAlignment}|{2 / (1 / a + 1 / b),ValueAlignment:F3}|");

// Expected output:
// Three classical Pythagorean means of 3 and 4:
// |Arithmetic|  3.500|
// |Geometric|  3.464|
// |Harmonic |  3.429|

As the example output shows, if the length of the formatted expression result exceeds specified field width, the alignment value is ignored.

For more information, see the Alignment Component section of the Composite Formatting topic.

How to use escape sequences in an interpolated string

Interpolated strings support all escape sequences that can be used in ordinary string literals. For more information, see String escape sequences.

To interpret escape sequences literally, use a verbatim string literal. A verbatim interpolated string starts with the $ character followed by the @ character.

To include a brace, "{" or "}", in a result string, use two braces, "{{" or "}}". For more information, see the Escaping Braces section of the Composite Formatting topic.

The following example shows how to include braces in a result string and construct a verbatim interpolated string:

var xs = new int[] { 1, 2, 7, 9 };
var ys = new int[] { 7, 9, 12 };
Console.WriteLine($"Find the intersection of the {{{string.Join(", ",xs)}}} and {{{string.Join(", ",ys)}}} sets.");

var userName = "Jane";
var stringWithEscapes = $"C:\\Users\\{userName}\\Documents";
var verbatimInterpolated = $@"C:\Users\{userName}\Documents";
Console.WriteLine(stringWithEscapes);
Console.WriteLine(verbatimInterpolated);

// Expected output:
// Find the intersection of the {1, 2, 7, 9} and {7, 9, 12} sets.
// C:\Users\Jane\Documents
// C:\Users\Jane\Documents

How to use a ternary conditional operator ?: in an interpolated expression

As the colon (":") has special meaning in an item with an interpolated expression, in order to use a conditional operator in an expression, enclose it in parentheses, as the following example shows:

var rand = new Random();
for (int i = 0; i < 7; i++)
{
    Console.WriteLine($"Coin flip: {(rand.NextDouble() < 0.5 ? "heads" : "tails")}");
}

How to create a culture-specific result string with string interpolation

By default, an interpolated string uses the current culture defined by the CultureInfo.CurrentCulture property for all formatting operations. Use implicit conversion of an interpolated string to a System.FormattableString instance and call its ToString(IFormatProvider) method to create a culture-specific result string. The following example shows how to do that:

var cultures = new System.Globalization.CultureInfo[]
{
    System.Globalization.CultureInfo.GetCultureInfo("en-US"),
    System.Globalization.CultureInfo.GetCultureInfo("en-GB"),
    System.Globalization.CultureInfo.GetCultureInfo("nl-NL"),
    System.Globalization.CultureInfo.InvariantCulture
};

var date = DateTime.Now;
var number = 31_415_926.536;
FormattableString message = $"{date,20}{number,20:N3}";
foreach (var culture in cultures)
{
    var cultureSpecificMessage = message.ToString(culture);
    Console.WriteLine($"{culture.Name,-10}{cultureSpecificMessage}");
}

// Expected output is like:
// en-US       5/17/18 3:44:55 PM      31,415,926.536
// en-GB      17/05/2018 15:44:55      31,415,926.536
// nl-NL        17-05-18 15:44:55      31.415.926,536
//            05/17/2018 15:44:55      31,415,926.536

As the example shows, you can use one FormattableString instance to generate multiple result strings for various cultures.

How to create a result string using the invariant culture

Along with the FormattableString.ToString(IFormatProvider) method, you can use the static FormattableString.Invariant method to resolve an interpolated string to a result string for the InvariantCulture. The following example shows how to do that:

string messageInInvariantCulture = FormattableString.Invariant($"Date and time in invariant culture: {DateTime.Now}");
Console.WriteLine(messageInInvariantCulture);

// Expected output is like:
// Date and time in invariant culture: 05/17/2018 15:46:24

Conclusion

This tutorial describes common scenarios of string interpolation usage. For more information about string interpolation, see the String interpolation topic. For more information about formatting types in .NET, see the Formatting Types in .NET and Composite formatting topics.

See also