Интерполяция строк с помощью $
Символ $
определяет строковый литерал как интерполированную строку. Интерполированная строка — это строковый литерал, который может содержать выражения интерполяции. При разрешении интерполированной строки в результирующем коде компилятор заменяет элементы выражения интерполяции строковыми представлениями результатов выражения.
Интерполяция строк предоставляет легко читаемый и удобный синтаксис для форматирования строк. Его проще читать, чем составное форматирование строк. В следующем примере обе этих функции используются для получения одинаковых выходных данных:
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.
Начиная с C# 10, можно использовать интерполированную строку для инициализации константной строки. Это можно сделать, только если все выражения интерполяции в интерполированной строке также являются константными строками.
Структура интерполированной строки
Для определения строкового литерала в качестве интерполированной строки добавьте к началу символ $
. Между $
и "
в начале строкового литерала не может быть пробела.
Структура элемента с выражением интерполяции выглядит следующим образом:
{<interpolationExpression>[,<alignment>][:<formatString>]}
Элементы в квадратных скобках являются необязательными. Каждый из элементов описан в таблице ниже:
Элемент | Description |
---|---|
interpolationExpression |
Выражение, создающее форматируемый результат. Если выражение имеет значение null , выходные данные — пустая строка (String.Empty). |
alignment |
Константное выражение, значение которого определяет минимальное количество символов в строковом представлении результата выражения. Если положительный результат, строковое представление выровнено по правому краю; Значение |
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#. Вы можете также просмотреть другой учебник по интерполяции строк в C#. В этом учебнике показано, как использовать интерполированные строки для создания форматированных строк.
Компиляция интерполированных строк
Начиная с C# 10 и .NET 6 компилятор проверяет, назначена ли интерполированная строка типу, удовлетворяющему шаблону интерполированного обработчика строк. Интерполированный обработчик строк — это тип, который преобразует интерполированную строку в результирующую строку. Если интерполированная строка имеет тип string
, он обрабатывается с System.Runtime.CompilerServices.DefaultInterpolatedStringHandlerпомощью . Пример пользовательского обработчика интерполированной строки см. в руководстве по написанию пользовательского обработчика интерполяции строк. Использование интерполированного обработчика строк — это расширенный сценарий, который обычно требуется по соображениям производительности.
Примечание.
Одним из побочных эффектов интерполированных обработчиков строк является то, что настраиваемый обработчик, включая System.Runtime.CompilerServices.DefaultInterpolatedStringHandler, может не оценивать все выражения интерполяции в интерполированной строке во всех условиях. Это означает, что побочные эффекты этих выражений могут не возникать.
Перед C# 10, если интерполированная строка имеет тип string
, обычно она преобразуется в String.Format вызов метода. Компилятор может заменить String.Format String.Concat его, если проанализированное поведение будет эквивалентно объединениям.
Если интерполированная строка имеет тип IFormattable или FormattableString, компилятор создает вызов метода FormattableStringFactory.Create.
Спецификация языка C#
Дополнительные сведения см. в разделе интерполированных строковых выражений спецификации языка C# и следующих новых спецификаций компонентов:
- C# 10 — улучшены интерполированные строки
- C# 11 — необработанные строковые литералы
- C# 11 — новые строки в интерполяциях строк