Поделиться через


Интерполяция строк с помощью $

Символ $ определяет строковый литерал как интерполированную строку. Интерполированная строка — это строковый литерал, который может содержать выражения интерполяции. При разрешении интерполированной строки в результирующую строку компилятор заменяет элементы с интерполяционными выражениями строковыми представлениями результатов этих выражений.

Интерполяция строк обеспечивает более читаемый и удобный синтаксис для форматирования строк. Проще читать, чем составное форматирование строк. В следующем примере оба компонента используются для создания одинаковых выходных данных:

var name = "Mark";
var date = DateTime.Now;

// Composite formatting:
Console.WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date.DayOfWeek, date);
// String interpolation:
Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
// Both calls produce the same output that is similar to:
// Hello, Mark! Today is Wednesday, it's 19:40 now.

Интерполированную строку можно использовать для инициализации константы строки. Это можно сделать, только если все выражения интерполяции в интерполированной строке также являются константными строками.

Структура интерполированной строки

Чтобы определить строковый литерал как интерполированную строку, добавьте в начало символ $. Между $ и ", начинающим строковый литерал, не должно быть пробелов.

Структура элемента с выражением интерполяции выглядит следующим образом:

{<interpolationExpression>[,<width>][:<formatString>]}

Элементы в квадратных скобках являются необязательными. В следующей таблице описан каждый элемент:

Элемент Описание
interpolationExpression Выражение, которое создает результат для форматирования. Если выражение имеет значение null, выходные данные — пустая строка (String.Empty).
width Константное выражение, значение которого определяет минимальное число символов в строковом представлении результата выражения. Если значение положительное, строковое представление выровнено по правому краю; если отрицательное, выровнено по левому краю. Дополнительные сведения см. в разделе компонента Width статьи о составном форматировании .
formatString Строка формата, поддерживаемая типом результата выражения. Дополнительные сведения см. в разделе компонента "Формат строки " статьи о составном форматировании .

В следующем примере используются необязательные компоненты форматирования, описанные в предыдущей таблице:

Console.WriteLine($"|{"Left",-7}|{"Right",7}|");

const int FieldWidthRightAligned = 20;
Console.WriteLine($"{Math.PI,FieldWidthRightAligned} - default formatting of the pi number");
Console.WriteLine($"{Math.PI,FieldWidthRightAligned:F3} - display only three decimal digits of the pi number");
// Output is:
// |Left   |  Right|
//     3.14159265358979 - default formatting of the pi number
//                3.142 - display only three decimal digits of the pi number

Начиная с C# 11, можно использовать новые строки в выражении интерполяции, чтобы сделать код выражения более читаемым. В следующем примере показано, как новые строки могут улучшить удобочитаемость выражения, включающего сопоставление шаблонов:

string message = $"The usage policy for {safetyScore} is {
    safetyScore switch
    {
        > 90 => "Unlimited usage",
        > 80 => "General usage, with daily safety check",
        > 70 => "Issues must be addressed within 1 week",
        > 50 => "Issues must be addressed within 1 day",
        _ => "Issues must be addressed before continued use",
    }
    }";

Интерполированные необработанные строковые литералы

Начиная с C# 11, можно использовать интерполированный необработанный строковый литерал, как показано в следующем примере:

int X = 2;
int Y = 3;

var pointMessage = $"""The point "{X}, {Y}" is {Math.Sqrt(X * X + Y * Y):F3} from the origin""";

Console.WriteLine(pointMessage);
// Output is:
// The point "2, 3" is 3.606 from the origin

Чтобы внедрить { и } символы в результируемую строку, запустите интерполированный необработанный строковый литерал с несколькими $ символами. При этом любая последовательность символов { или }, которая меньше количества символов $, будет внедрена в результирующую строку. Чтобы заключить любое выражение интерполяции в эту строку, необходимо использовать то же количество фигурных скобок, что и количество $ символов, как показано в следующем примере:

int X = 2;
int Y = 3;

var pointMessage = $$"""{The point {{{X}}, {{Y}}} is {{Math.Sqrt(X * X + Y * Y):F3}} from the origin}""";
Console.WriteLine(pointMessage);
// Output is:
// {The point {2, 3} is 3.606 from the origin}

В предыдущем примере интерполированный строковый литерал начинается с двух $ символов. Необходимо поместить каждое выражение интерполяции между двойными скобками ({{ и }}). Одна фигурная скобка внедрена в результирующую строку. Если необходимо внедрить повторяющиеся { или } символы в результирующую строку, используйте соответствующее число $ символов, чтобы обозначить интерполируемый необработанный строковый литерал. Если строковый литерал имеет более повторяющиеся фигурные скобки, чем число $ символов, { и } символы группируются изнутри в сторону. В предыдущем примере литерал The point {{{X}}, {{Y}}} интерпретирует {{X}} и {{Y}} как интерполированные выражения. Внешние { и } включаются в выходную строку.

Специальные символы

Чтобы включить фигурную скобку "{" или "}", в текст, созданный интерполированной строкой, используйте две фигурные скобки: "{" или "}}". Дополнительные сведения см. в разделе "Экранирование фигурных скобок" статьи о составном форматировании.

Как двоеточие (":") имеет особое значение в элементе выражения интерполяции, чтобы использовать условный оператор в выражении интерполяции. Заключите это выражение в скобки.

Пример ниже демонстрирует, как включить фигурную скобку в строку результата. В нем также показано, как использовать условный оператор:

string name = "Horace";
int age = 34;
Console.WriteLine($"He asked, \"Is your name {name}?\", but didn't wait for a reply :-{{");
Console.WriteLine($"{name} is {age} year{(age == 1 ? "" : "s")} old.");
// Output is:
// He asked, "Is your name Horace?", but didn't wait for a reply :-{
// Horace is 34 years old.

Интерполированная дословная строка начинается с символов $ и @. Вы можете использовать $ и @ в любом порядке: как $@"...", так и @$"..." являются допустимыми интерполированными дословными строками. Дополнительные сведения о подробных строках см. в статьях о строке и подробных идентификаторах .

Форматирование, характерное для конкретной культуры

По умолчанию интерполированная строка использует текущую культуру, определенную свойством CultureInfo.CurrentCulture для всех операций форматирования.

Чтобы разрешить интерполированную строку в строку результата, зависящую от языковых и региональных параметров, используйте метод String.Create(IFormatProvider, DefaultInterpolatedStringHandler), который доступен начиная с .NET 6. Следующий пример показывает, как это сделать:

double speedOfLight = 299792.458;

System.Globalization.CultureInfo.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("nl-NL");
string messageInCurrentCulture = $"The speed of light is {speedOfLight:N3} km/s.";

var specificCulture = System.Globalization.CultureInfo.GetCultureInfo("en-IN");
string messageInSpecificCulture = string.Create(
    specificCulture, $"The speed of light is {speedOfLight:N3} km/s.");

string messageInInvariantCulture = string.Create(
    System.Globalization.CultureInfo.InvariantCulture, $"The speed of light is {speedOfLight:N3} km/s.");

Console.WriteLine($"{System.Globalization.CultureInfo.CurrentCulture,-10} {messageInCurrentCulture}");
Console.WriteLine($"{specificCulture,-10} {messageInSpecificCulture}");
Console.WriteLine($"{"Invariant",-10} {messageInInvariantCulture}");
// Output is:
// nl-NL      The speed of light is 299.792,458 km/s.
// en-IN      The speed of light is 2,99,792.458 km/s.
// Invariant  The speed of light is 299,792.458 km/s.

В .NET 5 и более ранних версиях .NET используйте неявное преобразование интерполированной строки в FormattableString экземпляр. Затем можно использовать метод экземпляра FormattableString.ToString(IFormatProvider) или статический FormattableString.Invariant метод для создания строки результата, которая учитывает культурные особенности. Следующий пример показывает, как это сделать:

double speedOfLight = 299792.458;
FormattableString message = $"The speed of light is {speedOfLight:N3} km/s.";

var specificCulture = System.Globalization.CultureInfo.GetCultureInfo("en-IN");
string messageInSpecificCulture = message.ToString(specificCulture);
Console.WriteLine(messageInSpecificCulture);
// Output:
// The speed of light is 2,99,792.458 km/s.

string messageInInvariantCulture = FormattableString.Invariant(message);
Console.WriteLine(messageInInvariantCulture);
// Output is:
// The speed of light is 299,792.458 km/s.

Дополнительные сведения о настраиваемом форматировании см. в разделе "Настраиваемое форматирование с помощью ICustomFormatter" статьи "Типы форматирования в .NET".

Другие ресурсы

Если вы не знакомы с интерполяцией строк, ознакомьтесь с интерактивным руководством по интерполяции строк в C# . В этом руководстве показано, как использовать интерполированные строки для создания форматированных строк.

Компиляция интерполированных строк

Компилятор проверяет, назначена ли интерполированная строка типу, удовлетворяющему шаблону интерполированного обработчика строк. Интерполированный обработчик строк — это тип, который преобразует интерполированную строку в результирующую строку. Если интерполированная строка имеет тип string, она обрабатывается с помощью System.Runtime.CompilerServices.DefaultInterpolatedStringHandler. Пример пользовательского обработчика интерполированной строки см. в руководстве по написанию пользовательского обработчика интерполяции строк . Использование интерполированного обработчика строк — это расширенный сценарий, который обычно требуется по соображениям производительности.

Замечание

Одним из побочных эффектов интерполированных обработчиков строк является то, что настраиваемый обработчик, включая System.Runtime.CompilerServices.DefaultInterpolatedStringHandler, может не оценивать все выражения интерполяции в интерполированной строке во всех условиях. Это означает, что побочные эффекты этих выражений могут не возникать.

Если интерполированная строка имеет тип string, он обычно преобразуется в вызов метода String.Format. Компилятор может заменить String.Format на String.Concat, если проанализированное поведение будет эквивалентно конкатенации.

Если интерполированная строка имеет тип IFormattable или FormattableStringкомпилятор создает вызов FormattableStringFactory.Create метода.

Спецификация языка C#

Дополнительные сведения см. в разделе интерполированных строковых выраженийспецификации языка C# и следующих новых спецификаций компонентов:

См. также