Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Wskazówka
Ten artykuł jest częścią sekcji Podstawy dla deweloperów, którzy już znają co najmniej jeden język programowania i uczą się języka C#. Jeśli dopiero zaczynasz programować, najpierw zacznij od samouczków Wprowadzenie .
Pochodzi z innego języka? Interpolacja ciągów w języku C# działa podobnie jak literały szablonu w języku JavaScript (`${x}`) lub ciągi f w Python (f"{x}"). Wyrażenie wewnątrz {} może być dowolnym prawidłowym wyrażeniem języka C#, a specyfikatory formatowania i wyrównania można dodawać bez opuszczania ciągu.
Interpolacja łańcuchów umożliwia osadzanie wyrażeń bezpośrednio w literałach łańcuchowych poprzez poprzedzenie literału prefiksem $:
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);
// => 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
Każda { } z nich jest wyrażeniem interpolacji. Język C# oblicza wyrażenie, konwertuje wynik na ciąg, wywołując jego ToString() metodę, i zamienia tekst na wynik. Interpolacja ciągu znaków dla wyrażenia null to pusty ciąg znaków. W większości przypadków konwersja domyślna generuje żądane dane wyjściowe i nie trzeba wykonywać nic więcej.
Ciągi interpolowane są bardziej czytelną alternatywą dla String.Format i obsługują pełny zestaw funkcji formatowania złożonego. Wszystko, co można zrobić za pomocą klasycznego pozycyjnego ciągu formatującego — specyfikatory formatu, wyrównanie, formatowanie zależne od kultury i stałe ciągi znaków — można również zrobić za pomocą ciągu interpolowanego. W pozostałej części tego artykułu omówiono te opcje. Skontaktuj się z nimi tylko wtedy, gdy potrzebujesz bardziej precyzyjnej kontroli nad wynikiem; w przeciwnym razie wystarczy zwykły $"{expression}" formularz.
Aby zapoznać się z omówieniem składni i bazowych typów procedur obsługi w dokumentacji języka, zobacz dokumentację referencyjną ciągów interpolowanych. W przypadku zagadnień związanych z wydajnością, takich jak interpolacja Span<char> i niestandardowe programy obsługi ciągów interpolowanych, zobacz Operacje na ciągach.
Zastosuj ciąg formatujący
Aby określić, jak jest formatowany wynik wyrażenia, po wyrażeniu umieść dwukropek oraz standardowy lub niestandardowy ciąg formatujący:
{<expression>:<formatString>}
Poniższy przykład formatuje wartość DateTime i wartość Double:
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}.");
// => On Sunday, November 25, 1731 L. Euler introduced the letter e to denote 2.71828.
Ustawianie szerokości i wyrównania pola
Aby wygenerować wyrównane dane wyjściowe, postępuj zgodnie z wyrażeniem z przecinkiem i minimalną szerokością pola. Szerokości dodatnie wyrównają wartość do prawej, a szerokości ujemne wyrównają ją do lewej:
{<expression>,<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}|");
}
// => 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 potrzebujesz zarówno wyrównania, jak i ciągu formatu, najpierw podaj wyrównanie:
{<expression>,<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}|");
// => Three classical Pythagorean means of 3 and 4:
// => |Arithmetic| 3.500|
// => |Geometric| 3.464|
// => |Harmonic | 3.429|
Jeśli sformatowana wartość jest dłuższa niż żądana szerokość, język C# ignoruje szerokość i emituje pełną wartość.
Poprzedź nawiasy klamrowe znakiem ucieczki i użyj sekwencji ucieczki
Ciągi interpolowane obsługują te same sekwencje ucieczki co zwykłe literały ciągu. Aby uwzględnić w wyniku dosłowny znak { lub }, należy go podwoić ({{ lub }}).
W przypadku ścieżek i innych ciągów zawierających ukośniki odwrotne preferuj interpolowany surowy literał ciągu znaków ($"""...""") zamiast starszej formy dosłownej ($@"..."). Nieprzetworzone literały ciągu nie przetwarzają sekwencji ucieczki, więc ukośniki odwrotne są wyświetlane as-is:
int[] xs = [1, 2, 7, 9];
int[] ys = [7, 9, 12];
Console.WriteLine($"Find the intersection of the {{{string.Join(", ", xs)}}} and {{{string.Join(", ", ys)}}} sets.");
// => Find the intersection of the {1, 2, 7, 9} and {7, 9, 12} sets.
var userName = "Jane";
var stringWithEscapes = $"C:\\Users\\{userName}\\Documents";
var rawInterpolated = $"""C:\Users\{userName}\Documents""";
Console.WriteLine(stringWithEscapes);
Console.WriteLine(rawInterpolated);
// => C:\Users\Jane\Documents
// => C:\Users\Jane\Documents
Używanie wyrażenia warunkowego
Dwukropek ma specjalne znaczenie wewnątrz wyrażenia interpolowanego, więc ujmij wyrażenie warunkowe w nawiasy:
var rand = new Random(42);
for (int i = 0; i < 3; i++)
{
Console.WriteLine($"Coin flip: {(rand.NextDouble() < 0.5 ? "heads" : "tails")}");
}
Rozciągnij wyrażenie na wiele wierszy
Aby uzyskać lepszą czytelność, podziel długie wyrażenia interpolacji na wiele wierszy. Wyrażenia interpolowane wielowierszowe są dostępne od wersji C# 11. W poniższym przykładzie dodano nowe linie między znakami { i } w celu oddzielenia wyrażeń interpolowanych od tekstu literału:
int[] numbers = [3, 1, 4, 1, 5, 9, 2, 6];
Console.WriteLine($"Total: {
numbers.Sum()
}, average: {numbers.Average():F2}.");
// => Total: 31, average: 3.88.
Tworzenie ciągów stałych
Stałe ciągi interpolowane można tworzyć, gdy każde wyrażenie interpolowane jest stałą wartością. Dzięki temu można go używać dla argumentów atrybutów, switch wzorców i innych kontekstów, które wymagają stałych czasu kompilacji:
const string Audience = "world";
const string Greeting = $"Hello, {Audience}!";
Console.WriteLine(Greeting);
// => Hello, world!
Formatowanie z określoną kulturą
Domyślnie wartości ciągów interpolowanych są formatowane przy użyciu CultureInfo.CurrentCulturemetody , która wpływa na reprezentacje daty, liczby i waluty. Aby uzyskać deterministyczne dane wyjściowe, przekaż jawnie określoną kulturę do String.Create(IFormatProvider, DefaultInterpolatedStringHandler):
CultureInfo[] cultures =
[
CultureInfo.GetCultureInfo("en-US"),
CultureInfo.GetCultureInfo("en-GB"),
CultureInfo.GetCultureInfo("nl-NL"),
CultureInfo.InvariantCulture
];
var date = new DateTime(2026, 5, 21, 12, 35, 31);
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 5/21/2026 12:35:31 PM 31,415,926.536
// => en-GB 21/05/2026 12:35:31 31,415,926.536
// => nl-NL 21-05-2026 12:35:31 31.415.926,536
// => 05/21/2026 12:35:31 31,415,926.536
W przypadku niezmiennych danych wyjściowych (dzienniki, formaty plików, dane z możliwością odczytu maszynowego), przekaż polecenie CultureInfo.InvariantCulture:
var timestamp = new DateTime(2026, 5, 21, 15, 46, 24);
string message = string.Create(CultureInfo.InvariantCulture, $"Date and time in invariant culture: {timestamp}");
Console.WriteLine(message);
// => Date and time in invariant culture: 05/21/2026 15:46:24