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


Интерполяция строк в C#

В этом руководстве показано, как использовать интерполяцию строк для форматирования и включения выражений в результирующий текст. В примерах предполагается, что вы знакомы с основными понятиями C# и форматированием типов .NET. Дополнительные сведения о типах форматирования в .NET см. в разделе "Типы форматирования" в .NET.

Введение

Чтобы определить строковый литерал как интерполированную строку, добавьте в начало символ $. Можно внедрить любое допустимое выражение C#, возвращающее значение в интерполированной строке. В следующем примере после вычисления выражения его результат преобразуется в строку и включается в результируемую строку:

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);
// 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

Как показано в примере, вы включаете выражение в интерполированную строку, заключив его с фигурными скобками:

{<interpolationExpression>}

Интерполированные строки поддерживают все возможности функции составного форматирования строки . Это делает их более читаемой альтернативой использованию String.Format метода. Каждая интерполированная строка должна иметь следующее:

  • Строковый литерал, начинающийся с символа $ перед символом открывающей кавычки. Между символом $ и кавычками не может быть пробелов.
  • Одно или несколько выражений интерполяции. Вы указываете выражение интерполяции с открывающей и закрывающей скобкой ({ и }). Можно поместить любое выражение C#, возвращающее значение (включая null) в фигурные скобки.

C# вычисляет выражение между { символами и } символами со следующими правилами:

  • Если выражение интерполяции вычисляется в null, используется пустая строка ("", или String.Empty) .
  • Если выражение интерполяции не равен null, обычно вызывается метод возвращаемого типа ToString.

Указание строки формата для выражения интерполяции

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

{<interpolationExpression>:<formatString>}

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

var date = new DateTime(1731, 11, 25);
Console.WriteLine($"On {date:dddd, MMMM dd, yyyy} L. Euler introduced the letter e to denote {Math.E:F5}.");
// Output:
// On Sunday, November 25, 1731 L. Euler introduced the letter e to denote 2.71828.

Дополнительные сведения см. в разделе компонента "Формат строки " статьи о составном форматировании .

Управление шириной поля и выравниванием форматированного выражения интерполяции

Чтобы указать минимальную ширину поля и выравнивание результата отформатированного выражения, следуйте выражению интерполяции с запятыми (",") и константным выражением:

{<interpolationExpression>,<width>}

В следующем примере кода используется минимальная ширина поля для создания табличных выходных данных:

var titles = new Dictionary<string, string>()
{
    ["Doyle, Arthur Conan"] = "Hound of the Baskervilles, The",
    ["London, Jack"] = "Call of the Wild, The",
    ["Shakespeare, William"] = "Tempest, The"
};

Console.WriteLine("Author and Title List");
Console.WriteLine();
Console.WriteLine($"|{"Author",-25}|{"Title",30}|");
foreach (var title in titles)
{
    Console.WriteLine($"|{title.Key,-25}|{title.Value,30}|");
}
// Output:
// Author and Title List
// 
// |Author                   |Title                          |
// |Doyle, Arthur Conan      |Hound of the Baskervilles, The |
// |London, Jack             |         Call of the Wild, The |
// |Shakespeare, William     |                  Tempest, The |

Если значение ширины положительное, результат отформатированного выражения выровнен по правому краю; если отрицательное, результат выровнен по левому краю. Удалите знаки - перед описательом ширины и снова запустите пример, чтобы просмотреть результаты.

Если необходимо указать ширину и строку формата, начните с компонента ширины:

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

В следующем примере показано, как указать ширину и выравнивание и использовать символы канала ("|") для разделителя текстовых полей:

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}|");
// Output:
// Three classical Pythagorean means of 3 and 4:
// |Arithmetic|  3.500|
// |Geometric|  3.464|
// |Harmonic |  3.429|

Как показано в примере выходных данных, если длина отформатированного результата выражения превышает указанную ширину поля, значение ширины игнорируется.

Дополнительные сведения см. в разделе компонента Width статьи о составном форматировании .

Использование escape-последовательностей в интерполированной строке

Интерполированные строки поддерживают все экранирующие последовательности, которые можно использовать в обычных строковых литералах. Дополнительные сведения см. в разделе "Escape-последовательности строк".

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

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

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

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.");
// Output:
// Find the intersection of the {1, 2, 7, 9} and {7, 9, 12} sets.

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

Начиная с C# 11, можно использовать интерполированные необработанные строковые литералы.

Использование тернарного условного оператора ?: в выражении интерполяции

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

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

Как создать строку, специфичную для культуры, с использованием интерполяции строк

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

Начиная с .NET 6, можно использовать метод String.Create(IFormatProvider, DefaultInterpolatedStringHandler) для преобразования интерполированной строки в культурно-специфичную строку результата, как показано в следующем примере:

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;
foreach (var culture in cultures)
{
    var cultureSpecificMessage = string.Create(culture, $"{date,23}{number,20:N3}");
    Console.WriteLine($"{culture.Name,-10}{cultureSpecificMessage}");
}
// Output is similar to:
// en-US       8/27/2023 12:35:31 PM      31,415,926.536
// en-GB         27/08/2023 12:35:31      31,415,926.536
// nl-NL         27-08-2023 12:35:31      31.415.926,536
//               08/27/2023 12:35:31      31,415,926.536

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

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,23}{number,20:N3}";
foreach (var culture in cultures)
{
    var cultureSpecificMessage = message.ToString(culture);
    Console.WriteLine($"{culture.Name,-10}{cultureSpecificMessage}");
}
// Output is similar to:
// en-US       8/27/2023 12:35:31 PM      31,415,926.536
// en-GB         27/08/2023 12:35:31      31,415,926.536
// nl-NL         27-08-2023 12:35:31      31.415.926,536
//               08/27/2023 12:35:31      31,415,926.536

Как показано в примере, можно использовать один FormattableString экземпляр для создания нескольких результирующих строк для различных культурных настроек.

Создание строки результата с использованием инвариантной культуры

Начиная с .NET 6, используйте метод String.Create(IFormatProvider, DefaultInterpolatedStringHandler) для преобразования интерполированной строки в результирующую строку для InvariantCulture, как показано в следующем примере.

string message = string.Create(CultureInfo.InvariantCulture, $"Date and time in invariant culture: {DateTime.Now}");
Console.WriteLine(message);
// Output is similar to:
// Date and time in invariant culture: 05/17/2018 15:46:24

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

string message = FormattableString.Invariant($"Date and time in invariant culture: {DateTime.Now}");
Console.WriteLine(message);
// Output is similar to:
// Date and time in invariant culture: 05/17/2018 15:46:24

Заключение

В этом руководстве описаны распространенные сценарии использования интерполяции строк. Дополнительные сведения о интерполяции строк см. в разделе "Интерполяция строк". Дополнительные сведения о типах форматирования в .NET см. в статьях о форматировании .NET и составных статьях.

См. также