Udostępnij za pośrednictwem


Interpolacja ciągów w języku C#

W tym samouczku pokazano, jak używać interpolacji ciągów do formatowania i włączania wyników wyrażeń do ciągu wynikowego. W przykładach założono, że znasz podstawowe pojęcia dotyczące języka C# i formatowanie typów platformy .NET. Aby uzyskać więcej informacji na temat typów formatowania na platformie .NET, zobacz Typy formatowania na platformie .NET.

Wprowadzenie

Aby zidentyfikować literał ciągu jako ciąg interpolowany, dodaj go do symbolu $ . Możesz osadzić dowolne prawidłowe wyrażenie języka C#, które zwraca wartość w ciągu interpolowanym. W poniższym przykładzie, gdy tylko wyrażenie zostanie ocenione, jego wynik zostanie przekonwertowany na ciąg i uwzględniony w ciągu wynikowym:

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

Jak pokazano w przykładzie, wyrażenie jest uwzględniane w ciągu interpolowanym przez dołączenie go do nawiasów klamrowych:

{<interpolationExpression>}

Ciągi interpolowane obsługują wszystkie możliwości funkcji formatowania złożonego ciągu . To sprawia, że są bardziej czytelną alternatywą dla użycia String.Format metody. Każdy ciąg interpolowany musi mieć:

  • Literał ciągu, który rozpoczyna się od znaku $ przed otwierającym cudzysłowem. Między symbolem $ a znakiem cudzysłowu nie może być żadnych spacji.
  • Co najmniej jedno wyrażenie interpolacji. Wskazujesz wyrażenie interpolacji przy pomocy nawiasu klamrowego otwierającego i zamykającego ({ i }). Możesz umieścić dowolne wyrażenie języka C#, które zwraca wartość (w tym null) wewnątrz nawiasów klamrowych.

Język C# oblicza wyrażenie między znakami { i } następującymi regułami:

  • Jeśli wyrażenie interpolacji zwróci wartość null, zostanie użyty pusty ciąg (""lub String.Empty).
  • Jeśli wyrażenie interpolacji nie daje wartości null, zazwyczaj wywoływana jest metoda typu wynikowego ToString.

Jak określić ciąg formatu dla wyrażenia interpolacji

Aby określić ciąg formatu obsługiwany przez typ wyniku wyrażenia, postępuj zgodnie z wyrażeniem interpolacji z dwukropkiem (":") i ciągiem formatu:

{<interpolationExpression>:<formatString>}

W poniższym przykładzie pokazano, jak określić standardowe i niestandardowe ciągi formatu dla wyrażeń, które generują wyniki daty i godziny lub liczb:

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.

Aby uzyskać więcej informacji, zobacz sekcję Format składnika ciągu w artykule Dotyczącym formatowania złożonego.

Jak kontrolować szerokość pola i wyrównanie sformatowanego wyrażenia interpolacji

Aby określić minimalną szerokość pola i wyrównanie sformatowanego wyniku wyrażenia, po wyrażeniu interpolacji wstaw przecinek (",") i dodaj wyrażenie stałe.

{<interpolationExpression>,<width>}

Poniższy przykładowy kod używa minimalnej szerokości pola do utworzenia tabelarycznych danych wyjściowych:

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 |

Jeśli wartość szerokości jest dodatnia, wynik sformatowanego wyrażenia jest wyrównany do prawej; jeśli ujemna, jest wyrównany do lewej. - Usuń znaki przed specyfikatorem szerokości i uruchom ponownie przykład, aby wyświetlić wyniki.

Jeśli musisz określić zarówno szerokość, jak i ciąg formatu, zacznij od składnika width:

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

W poniższym przykładzie pokazano, jak określić szerokość i wyrównanie oraz użyć znaków kreski pionowej ("|") do rozdzielania pól tekstowych.

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|

Jak pokazano w przykładowych danych wyjściowych, jeśli długość sformatowanego wyniku wyrażenia przekracza określoną szerokość pola, wartość szerokości jest ignorowana.

Aby uzyskać więcej informacji, zobacz sekcję Składnik szerokości artykułu Formatowanie złożone .

Jak używać sekwencji ucieczki w ciągu interpolowanym

Ciągi interpolowane obsługują wszystkie sekwencje ucieczki, które mogą być używane w zwykłych literałach ciągów. Aby uzyskać więcej informacji, zobacz Sekwencje ucieczki ciągów.

Aby interpretować sekwencje ucieczki dosłownie, użyj literału ciągu verbatim. Ciąg dosłowny interpolowany rozpoczyna się od znaków $ i @. Można użyć poleceń $ i @ w dowolnej kolejności: zarówno ciągi interpolowane, jak $@"..." i @$"..." są prawidłowe ciągi dosłowne interpolacji.

Aby umieścić nawias klamrowy "{" lub "}" w ciągu wynikowym, użyj podwójnych nawiasów klamrowych "{{" lub "}}". Aby uzyskać więcej informacji, zobacz sekcję Escaping braces (Ucieczka nawiasów klamrowych) w artykule Dotyczącym formatowania złożonego.

W poniższym przykładzie pokazano, jak uwzględnić nawiasy klamrowe w ciągu wynikowym i utworzyć dosłowny ciąg interpolowany:

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

Począwszy od języka C# 11, można użyć interpolowanych nieprzetworzonych literałów ciągu.

Jak używaćternarnego operatora ?: warunkowego w wyrażeniu interpolacji

Ponieważ dwukropek (":") ma specjalne znaczenie w elemencie z wyrażeniem interpolacji, aby użyć operatora warunkowego w wyrażeniu, ująć go w nawiasy, jak pokazano w poniższym przykładzie:

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

Jak utworzyć ciąg wynikowy specyficzny dla kultury przy użyciu interpolacji ciągów

Domyślnie ciąg interpolowany używa bieżącej kultury zdefiniowanej CultureInfo.CurrentCulture przez właściwość dla wszystkich operacji formatowania.

Począwszy od platformy .NET 6, możesz użyć metody String.Create(IFormatProvider, DefaultInterpolatedStringHandler), aby sformułować ciąg interpolowany na ciąg wynikowy specyficzny dla kultury, co pokazano w następującym przykładzie.

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

We wcześniejszych wersjach platformy .NET, użyj niejawnej konwersji ciągu interpolowanego na wystąpienie System.FormattableString i wywołaj metodę ToString(IFormatProvider), aby utworzyć ciąg wynikowy specyficzny dla kultury. W poniższym przykładzie pokazano, jak to zrobić:

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

Jak pokazano w przykładzie, można użyć jednego FormattableString wystąpienia, aby wygenerować wiele ciągów wyników dla różnych kultur.

Jak utworzyć ciąg wynikowy przy użyciu niezmiennej kultury

Począwszy od platformy .NET 6, użyj metody String.Create(IFormatProvider, DefaultInterpolatedStringHandler), aby przekształcić ciąg interpolowany w ciąg wynikowy dla InvariantCulture, jak pokazano w poniższym przykładzie.

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

We wcześniejszych wersjach platformy .NET wraz z FormattableString.ToString(IFormatProvider) metodą można użyć metody statycznej FormattableString.Invariant , jak pokazano w poniższym przykładzie:

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

Podsumowanie

W tym samouczku opisano typowe scenariusze użycia interpolacji ciągów. Aby uzyskać więcej informacji na temat interpolacji ciągów, zobacz Interpolacja ciągów. Aby uzyskać więcej informacji na temat typów formatowania na platformie .NET, zobacz artykuły Formatting types in .NET and Composite formatting (Typy formatowania na platformie .NET i złożone).

Zobacz też