使用 字串插補 $

$ 特殊字元會將字串常值識別為「字串內插補點」。 插入字串是可能包含「內插補點運算式」的字串常值。 將插入字串解析為結果字串時,會將具有內插補點運算式之項目取代為運算式結果的字串表示。

字串插補提供更容易閱讀的方便語法來格式化字串。 比 字串複合格式更容易閱讀。 比較下列使用這兩個功能來產生相同輸出的範例:

string 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>[,<alignment>][:<formatString>]}

在方括號中的元素是選擇性的元素。 下表說明每個元素:

元素 描述
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");
// Expected output is:
// |Left   |  Right|
//     3.14159265358979 - default formatting of the pi number
//                3.142 - display only three decimal digits of the pi number

從 C# 10 開始,您可以使用字串插補來初始化常數位符串。 所有用於預留位置的運算式都必須是常數位符串。 換句話說,每個 插補運算式 都必須是字串,而且必須是編譯時間常數。

從 C# 11 開始,插補運算式可以包含分行符號。 和 } 之間的 { 文字必須是有效的 C#,因此可以包含可改善可讀性的分行符號。 下列範例顯示 newline 如何改善涉及模式比對的運算式可讀性:

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)} from the origin""";

Console.WriteLine(pointMessage);
// output:  The point "2, 3" is 3.605551275463989 from the origin.

您可以在插入的原始字串常值中使用多個 $ 字元,在輸出字串中內嵌 {} 字元,而不需逸出這些字元:

int X = 2;
int Y = 3;

var pointMessage = $$"""The point {{{X}}, {{Y}}} is {{Math.Sqrt(X * X + Y * Y)}} from the origin""";
Console.WriteLine(pointMessage);
// output:  The point {2, 3} is 3.605551275463989 from the origin.

如果您的輸出字串應該包含重複 {} 字元,您可以新增更多 $ 來指定插補字串。 {任何序列或 } 較短的序列 $ 都會內嵌在輸出字串中。 如上述範例所示,序列長度超過在輸出中內嵌額外 {} 字元的 $ 字元序列。 如果大括弧字元序列等於或大於字元序列 $ 的長度,編譯器就會發出錯誤。

您可以使用 .NET 7 SDK 試用這些功能。 或者,如果您有 .NET SDK 6.00.200 或更新版本,您可以將csproj檔案中的 元素設定 <LangVersion>preview

特殊字元

若要在插入字串所產生的文字中包含大括弧 "{" 或 "}",請使用雙大括弧 "{{" 或 "}}"。 如需詳細資訊,請參閱逸出大括號

由於冒號 (「:」) 在插補運算式專案中具有特殊意義,若要在插補運算式中使用 條件運算子 ,請將該運算式括在括弧中。

下列範例示範如何在結果字串中包含大括弧。 它也會示範如何使用條件運算子:

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.");
// Expected output is:
// He asked, "Is your name Horace?", but didn't wait for a reply :-{
// Horace is 34 years old.

插入的逐字字串開頭為 $ 字元,後面接著 @ 字元。 您可以依任何順序使用 $@ 權杖: $@"..."@$"..." 都是有效的插補逐字字串。 如需逐字字串的詳細資訊,請參閱 字串逐字識別碼 文章。

隱含轉換以及如何指定 IFormatProvider 實作

有三個來自插入字串的隱含轉換:

  1. 將插入字串轉換成 String 實例。 字串是插入字串解析的結果。 所有插補運算式專案都會取代為其結果正確格式化的字串表示。 此轉換會使用 CurrentCulture 來格式化運算式結果。

  2. 將插入字串轉換成 FormattableString 執行個體,以代表複合格式字串,並將運算式結果格式化。 那可讓您從單一 FormattableString 執行個體建立多個具有特定文化特性內容的結果字串。 若要這樣做,請呼叫下列其中一種方法:

    提供 ToString(IFormatProvider) 支援自訂格式之 IFormatProvider 介面的使用者定義實作。 如需詳細資訊,請參閱.NET 中格式化類型的ICustomFormatter一節。

  3. 將插入字串轉換成 IFormattable 執行個體,也可讓您從單一 IFormattable 執行個體建立多個具有特定文化特性內容的結果字串。

下列範例會使用隱含轉換成 FormattableString,來建立文化特性特定結果字串:

double speedOfLight = 299792.458;
FormattableString message = $"The speed of light is {speedOfLight:N3} km/s.";

System.Globalization.CultureInfo.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("nl-NL");
string messageInCurrentCulture = message.ToString();

var specificCulture = System.Globalization.CultureInfo.GetCultureInfo("en-IN");
string messageInSpecificCulture = message.ToString(specificCulture);

string messageInInvariantCulture = FormattableString.Invariant(message);

Console.WriteLine($"{System.Globalization.CultureInfo.CurrentCulture,-10} {messageInCurrentCulture}");
Console.WriteLine($"{specificCulture,-10} {messageInSpecificCulture}");
Console.WriteLine($"{"Invariant",-10} {messageInInvariantCulture}");
// Expected 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.

其他資源

如果您不熟悉字串插補,請參閱 C# 互動式插補中的字串插 補教學課程。 您也可以在 C# 教學課程中 檢查另一個字串插補。 該教學課程示範如何使用插補字串來產生格式化字串。

內插字串的編譯

如果內插字串的類型為 string,它通常會轉換成 String.Format 方法呼叫。 如果分析的行為相當於串連,編譯器可以將 String.Format 取代為 String.Concat

如果內插字串的類型為 IFormattableFormattableString,編譯器會產生 FormattableStringFactory.Create 方法的呼叫。

從 C# 10 開始,使用插補字串時,編譯器會檢查插入字串是否指派給符合 插入字串處理常式模式的類型。 插入字串處理常式是自訂類型,可將插入字串轉換成字串。 插補字串處理常式是進階案例,通常用於效能原因。 您可以瞭解在語言規格中建置插補字串處理常式的需求,以進行 插補字串改善。 您可以在 C# 的新功能一節中,建置一個 內插字串處理常式教學 課程。 在 .NET 6 中,當您針對 類型的 string 引數使用插補字串時,會由 System.Runtime.CompilerServices.DefaultInterpolatedStringHandler 處理插補字串。

注意

插入字串處理常式的其中一個副作用是自訂處理常式,包括 System.Runtime.CompilerServices.DefaultInterpolatedStringHandler ,可能不會在所有情況下,評估作為插補字串中預留位置的所有運算式。 這表示這些運算式中的副作用可能不會發生。

C# 語言規格

如需詳細資訊,請參閱C# 語言規格插補字串一節、C# 11 - 原始字串常值功能規格和C# 11 - 字串插補功能規格中的新行

另請參閱