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


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

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

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

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

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

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",
    }
    }";

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

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

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}} как интерполированные выражения. Внешние { и } включаются в выходную строку.

Подсказка

Visual Studio и комплект средств разработки C# предоставляют некоторые проверки и синтаксис выделения, когда необработанные строковые литералы содержат данные JSON или регулярные выражения.

Средства синтаксического анализа текста. Если средства уверены, что текст представляет JSON или регулярное выражение, редактор предоставляет цвет синтаксиса.

Вы можете улучшить этот интерфейс, добавив комментарий над объявлением, указывающим формат:

  • // lang=json указывает, что необработанный строковый литерал представляет данные JSON.
  • // lang=regex указывает, что необработанный строковый литерал представляет регулярное выражение.

Если необработанный строковый литерал используется в качестве аргумента, в котором параметр использует System.Diagnostics.CodeAnalysis.StringSyntaxAttribute формат, эти средства проверяют необработанный строковый литерал для некоторых типов форматов. Поддерживаются как JSON, так и regex.

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

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

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

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

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

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# и следующих новых спецификаций компонентов:

См. также