C# $字符串插值的使用
$ 字符
字符串插值(String Interpolation)有許多的實現(xiàn)方式,其中使用 $
字符在現(xiàn)代 C# 中時比較推薦的方式,它提供類似于 String.Format
的效果。
實際根據(jù) $ 使用場景的不同,編譯器會選擇用不同的方式實現(xiàn)字符串插值,String.Format 只是其中一種,具體見 實現(xiàn)細節(jié)
如下分別為使用 $
和 String.Format
的示例:
int value = 3; Debug.Log($"Value is {value}"); Debug.Log(String.Format("Value is {0}", value));
輸出結果為:
Value is 3
Value is 3
使用方式
創(chuàng)建內插字符串
字符串插值(String Interpolation) 是用來將表達式插入到字符串中的方式,簡單的示例如下所示:
string name = "wxj"; Debug.Log($"Hello,{name}.");
輸出結果為:
Hello,wxj.
其中 $"Hello,{name}.") 被稱為 內插字符串表達式(interpolated string expression)(下簡稱 內插表達式),最后輸出的 Hello,wxj. 被稱為 結果字符串(result string)
由上例可以看出字符串插值的兩個必要因素:
- 在字符串前需要有 $ 字符標記,且該字符與后續(xù)的 " 間不能有空格。
- 在內插表達式內部可以有一個或多個 {} ,其中包含著任何返回結果的 C# 表達式,表達式的返回值也可以為 null。
包含不同的數(shù)據(jù)類型
對于內插表達式中的各 C# 表達式可以是任何類型的,如下所示:
var item = (Name: "eggplant", Price: 1.99m, perPackage: 3); var date = DateTime.Now; Debug.Log($"On {date}, the price of {item.Name} was {item.Price} per {item.perPackage} items.");
輸出結果為:
On 12/10/2021 8:26:07 AM, the price of eggplant was 1.99 per 3 items.
可以看到該內插字符串表達式中包含有各種類型的表達式(string
,Decimal
,int
,DeltaTime
),在最終的結果中都被正確的解析。
內插字符串表達式,各表達式都會被轉換為 string
,且規(guī)則如下:
- 如果表達式結果為
null
,將其轉換為空字符串。 - 如果表達式結果不為
null
,對其調用ToString
函數(shù)。
控制內插表達式的格式
在內插表達式中,還可以控制各表達式轉換到 string
時的格式,如下所示:
DateTime date = DateTime.Now; float value = 1.12345678f; Debug.Log($"On {date}, value is {value}"); Debug.Log($"On {date:d}, value is {value:f3}");
輸出結果為:
On 12/10/2021 8:39:56 AM, value is 1.123457
On 12/10/2021, value is 1.123
在內插表達式中的各表達式中可以通過 :
后加控制的字符格式化輸出。如上例中的 d
和 f3
即為控制字符。
: 后的控制字符,相當于在調用 ToString 時作為形參控制表達式的輸出。
上述表達式等同于:
Debug.Log("On " + date.ToString("d") + ", value is " + value.ToString("f3"));
控制內插表達式的對齊方式
在內插表達式中的個表達式中可以通過 ,
后加數(shù)字來控制字符寬度和對其方式,如下所示:
var inventory = new Dictionary<string, int>() { ["hammer, ball pein"] = 14, ["hammer, ball pein a"] = 18, ["hammer, cross pein"] = 5, ["screwdriver, Phillips #2"] = 14 }; string result = $"|{"Item",-25}|{"Quantity",10}|\n"; foreach (var item in inventory) result += $"|{item.Key,-25}|{item.Value,10}|\n"; Debug.Log(result);
輸出結果為:
|Item | Quantity|
|hammer, ball pein | 14|
|hammer, ball pein a | 18|
|hammer, cross pein | 5|
|screwdriver, Phillips #2 | 14|
其中逗號后的數(shù)字,如果為負數(shù),則輸出為左對齊,如果為正數(shù)則右對齊。數(shù)字本身表示最少的字符數(shù)。因此如果顯示系統(tǒng)中每個字符的寬度是不相等的話,如 i
和 a
的寬度在某些顯示系統(tǒng)下會有較大差異,則即使控制字符寬度也無法實現(xiàn)對其的效果。
如下為相同輸出結果在 Unity 的 Console 面板中的展示:
表達式格式和對齊方式也可以一起設定,但需要首先設定對其方式,再設定格式。如下首先控制了左對齊,且字符數(shù)為 10 個,又設定輸出格式為當前小時數(shù):
Debug.Log($"[{DateTime.Now,-10:HH}]");
結果為:
[10 ]
內插表達式中使用轉義序列
如果要在內插表達式中可以使用轉義序列,當需要多次使用轉義序列時也可使用 原義標識符@ 替代。
如下所示,分別使用使用了轉義序列和原文標識符:
string userName = "wxj"; string stringWithEscapes = $"C:\\Users\\{userName}\\Documents"; string verbatimInterpolated = $@"C:\Users\{userName}\Documents"; Debug.Log(stringWithEscapes); Debug.Log(verbatimInterpolated);
輸出結果為:
C:\Users\wxj\Documents
C:\Users\wxj\Documents
C# 8.0 后,$ 與 @ 的先后順序不會造成任何影響。在早期版本中,必須先寫 $ 再寫 @。
在內插表達式中,如果需要輸入 {
,則按如下方式處理:
int[] values = new int[] { 1, 2 }; Debug.Log($"Value is {{{values[0]}, {values[1]}}}");
輸出結果為:
Value is {1, 2}
也可以通過 $@
的結合控制換行,如下:
var publishDate = new DateTime(2017, 12, 14); string str = $@"This post published on {publishDate:yyyy-MM-dd} is about interpolated strings."; Debug.Log(str);
此時輸出為:
This post published on 2017-12-14 is about
interpolated strings.
內插表達式中使用 ?: 運算符
因為 :
在內插表達式中用來指定格式,因此當使用 ?:
運算符時,必須定義在括號內。如下所示:
System.Random random = new System.Random(); for (int i = 0; i != 3; ++i) { Debug.Log($"Value is {(random.Next() % 2 == 1 ? "Odd" : "Even")}"); }
輸出結果為:
Even
Odd
Odd
實現(xiàn)細節(jié)
根據(jù) $
的實現(xiàn)方式的不同,編譯器會選擇用不同的方式實現(xiàn)字符串插值。
string.Concat
當插值的對象為類型為 string 時,編譯器會選擇使用 string.Concat
。
如下代碼:
string name = "meziantou"; string hello = $"Hello {name}!";
編譯器會將其轉換為:
string name = "meziantou"; string hello = string.Concat("Hello ", name, "!");
string.Format
如果插值的對象為類型為非 string 時,編譯器會選擇使用 string.Format
。
如下代碼:
DateTime now = DateTime.Now; string str = $"It is {now}";
編譯器會將其轉換為:
DateTime now = DateTime.Now; string str = string.Format("It is {0}", now);
FormattableString
如果插值的對象為類型為 Formattable String 時,編譯器會選擇使用 FormattableStringFactory.Create
創(chuàng)建一個新的 FormattableString
。
如下代碼:
object value1 = "Foo"; object value2 = "Bar"; FormattableString str = $"Test {value1} {value2}";
編譯器會將其轉換為:
object value1 = "Foo"; object value2 = "Bar"; FormattableString str = FormattableStringFactory.Create("Test {0} {1}", new object[] { value1, value2 });
當真正需要使用該 string 時,會調用 FormattableString.ToString
方法,將其轉換為 string。
constants(C# 10)
在 C# 10 中,支持將內插表達式的結果作為常量。如下所示:
const string Username = "meziantou"; const string Hello = $"Hello {Username}!"; // In previous C# version, you need to use the following concat syntax const string Hello2 = "Hello " + Username + "!";
Interpolated string handlers(C# 10)
C# 10 中針對高性能場景,引入了 InterpolatedStringHandlerArgument
,具體見:
String Interpolation in C# 10 and .NET 6 - .NET Blog (microsoft.com)
Reference
$ - string interpolation - C# reference | Microsoft Docs
String interpolation - C# tutorial | Microsoft Docs
String interpolation in C# | Microsoft Docs
Interpolated strings: advanced usages - Meziantou’s blog
到此這篇關于C# $字符串插值的使用的文章就介紹到這了,更多相關C# $字符串插值內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Unity中 ShaderGraph 實現(xiàn)旋渦傳送門效果入門級教程(推薦)
通過Twirl 旋轉節(jié)點對Gradient Noise 梯度噪聲節(jié)點進行操作,就可得到一個旋轉的旋渦效果。具體實現(xiàn)代碼跟隨小編一起通過本文學習下吧2021-07-07WinForm實現(xiàn)讀取Resource中文件的方法
這篇文章主要介紹了WinForm實現(xiàn)讀取Resource中文件的方法,很實用的一個功能,需要的朋友可以參考下2014-08-08