C# 10 來了,首先要介紹的是關於字串的新改變。
字串常數使用字串插補功能
C# 10 的字串常數可以使用字串插捕功能來合併不同的字串常值,例如:
const string Score = "99";
const string Name = "Bill";
const string Description = $"{Name}'s Score is {Score}";
不過這有個地方需要注意就是必須所有的都是字串常值,如果改成以下的寫法在目前是無法編譯成功的,期待下一版能有機會更進一步。
const int Score = 99;
const string Name = "Bill";
// 這會編譯失敗
const string Description = $"{Name}'s Score is {Score}";
字串插補處理常式
C# 10 這次對於字串的改變中最有趣的就是這一個功能,過去編譯器對於字串插補的處理大致上就是轉換成 String.Format 或是 String.Concat,現在帶來了字串插補處理常式 (Interpolated string handler),我們可以自己定義一個型別來客製化字串插補的處理過程。
定義字串插補處理常式有幾項規定:
- 型別必須套用 InterpolatedStringHandlerAttribute 。
- 必須有一個具備兩個 int 型別參數 -- literalLength and formatCount 的建構式
- 公開方法 – public void AppendLiteral(string s)
- 公開方法 – public void AppendFormatted<T>(T t)
例如:
[InterpolatedStringHandler]
struct CustomStringHandler
{
StringBuilder builder;
public CustomStringHandler (int literalLength, int formatCount)
{
builder = new StringBuilder(literalLength);
}
public void AppendLiteral(string s)
{
builder.Append(s);
}
public void AppendFormatted<T>(T t)
{
builder.Append(t?.ToString());
}
public override string ToString()
{
return builder.ToString();
}
}
稍微解釋一下裡面的意義:
- 建構式中的第一個參數代表傳入的字串常值的字元數,例如 $"today is {day}",這個敘述中的常值字元數為 9 – today(5)、is(2)、空格(2);第二個參數代表插值的數量,意即格式化字串的數量,說白了就是有幾組 {} 啦,在 $"today is {day}" 就是一組。
- AppendLiteral 方法會傳入字串常值。
- AppendFormatted<T> 方法則是傳入插值的部分。
運作方式
我們建立以下的方法來解釋它是怎麼運作的:
static void PrintText(CustomStringHandler handler)
{
Console.WriteLine(handler);
}
接著我們這麼呼叫 PrintText 方法:
PrintText($"字串插值列印, 時間 {DateTime.Now}, 這是結尾");
編譯器會將程式碼拓展成以下型式:
CustomStringHandler handler = new CustomStringHandler(17, 1);
handler.AppendLiteral("字串插值列印, 時間 ");
handler.AppendFormatted(DateTime.Now);
handler.AppendLiteral(", 這是結尾");
PrintText(handler.ToString());
這個功能有點裝飾器的感覺,可以在處理字串插捕的時候加入一些特定的處理。