使用 字串插補 $
$
特殊字元會將字串常值識別為「字串內插補點」。 插入字串是可能包含「內插補點運算式」的字串常值。 將插入字串解析為結果字串時,會將具有內插補點運算式之項目取代為運算式結果的字串表示。
字串插補提供更容易閱讀的方便語法來格式化字串。 比 字串複合格式更容易閱讀。 比較下列使用這兩個功能來產生相同輸出的範例:
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
實作
有三個來自插入字串的隱含轉換:
將插入字串轉換成 String 實例。 字串是插入字串解析的結果。 所有插補運算式專案都會取代為其結果正確格式化的字串表示。 此轉換會使用 CurrentCulture 來格式化運算式結果。
將插入字串轉換成 FormattableString 執行個體,以代表複合格式字串,並將運算式結果格式化。 那可讓您從單一 FormattableString 執行個體建立多個具有特定文化特性內容的結果字串。 若要這樣做,請呼叫下列其中一種方法:
- 產生 CurrentCulture 的結果字串的 ToString() 多載。
- 產生 InvariantCulture 的結果字串的 Invariant 方法。
- 產生指定文化特性的結果字串的 ToString(IFormatProvider) 方法。
提供 ToString(IFormatProvider) 支援自訂格式之 IFormatProvider 介面的使用者定義實作。 如需詳細資訊,請參閱.NET 中格式化類型的ICustomFormatter一節。
將插入字串轉換成 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。
如果內插字串的類型為 IFormattable 或 FormattableString,編譯器會產生 FormattableStringFactory.Create 方法的呼叫。
從 C# 10 開始,使用插補字串時,編譯器會檢查插入字串是否指派給符合 插入字串處理常式模式的類型。 插入字串處理常式是自訂類型,可將插入字串轉換成字串。 插補字串處理常式是進階案例,通常用於效能原因。 您可以瞭解在語言規格中建置插補字串處理常式的需求,以進行 插補字串改善。 您可以在 C# 的新功能一節中,建置一個 內插字串處理常式教學 課程。 在 .NET 6 中,當您針對 類型的 string
引數使用插補字串時,會由 System.Runtime.CompilerServices.DefaultInterpolatedStringHandler 處理插補字串。
注意
插入字串處理常式的其中一個副作用是自訂處理常式,包括 System.Runtime.CompilerServices.DefaultInterpolatedStringHandler ,可能不會在所有情況下,評估作為插補字串中預留位置的所有運算式。 這表示這些運算式中的副作用可能不會發生。
C# 語言規格
如需詳細資訊,請參閱C# 語言規格的插補字串一節、C# 11 - 原始字串常值功能規格和C# 11 - 字串插補功能規格中的新行。