C# $字符串插值的使用
$ 字符
字符串插值(String Interpolation)有許多的實現(xiàn)方式,其中使用 $ 字符在現(xiàn)代 C# 中時比較推薦的方式,它提供類似于 String.Format 的效果。
實際根據(jù) $ 使用場景的不同,編譯器會選擇用不同的方式實現(xiàn)字符串插值,String.Format 只是其中一種,具體見 實現(xiàn)細(xì)節(jié)
如下分別為使用 $ 和 String.Format的示例:
int value = 3;
Debug.Log($"Value is {value}");
Debug.Log(String.Format("Value is {0}", value));
輸出結(jié)果為:
Value is 3
Value is 3
使用方式
創(chuàng)建內(nèi)插字符串
字符串插值(String Interpolation) 是用來將表達(dá)式插入到字符串中的方式,簡單的示例如下所示:
string name = "wxj";
Debug.Log($"Hello,{name}.");
輸出結(jié)果為:
Hello,wxj.
其中 $"Hello,{name}.") 被稱為 內(nèi)插字符串表達(dá)式(interpolated string expression)(下簡稱 內(nèi)插表達(dá)式),最后輸出的 Hello,wxj. 被稱為 結(jié)果字符串(result string)
由上例可以看出字符串插值的兩個必要因素:
- 在字符串前需要有 $ 字符標(biāo)記,且該字符與后續(xù)的 " 間不能有空格。
- 在內(nèi)插表達(dá)式內(nèi)部可以有一個或多個 {} ,其中包含著任何返回結(jié)果的 C# 表達(dá)式,表達(dá)式的返回值也可以為 null。
包含不同的數(shù)據(jù)類型
對于內(nèi)插表達(dá)式中的各 C# 表達(dá)式可以是任何類型的,如下所示:
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.");
輸出結(jié)果為:
On 12/10/2021 8:26:07 AM, the price of eggplant was 1.99 per 3 items.
可以看到該內(nèi)插字符串表達(dá)式中包含有各種類型的表達(dá)式(string,Decimal,int,DeltaTime),在最終的結(jié)果中都被正確的解析。
內(nèi)插字符串表達(dá)式,各表達(dá)式都會被轉(zhuǎn)換為 string,且規(guī)則如下:
- 如果表達(dá)式結(jié)果為
null,將其轉(zhuǎn)換為空字符串。 - 如果表達(dá)式結(jié)果不為
null,對其調(diào)用ToString函數(shù)。
控制內(nèi)插表達(dá)式的格式
在內(nèi)插表達(dá)式中,還可以控制各表達(dá)式轉(zhuǎn)換到 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}");
輸出結(jié)果為:
On 12/10/2021 8:39:56 AM, value is 1.123457
On 12/10/2021, value is 1.123
在內(nèi)插表達(dá)式中的各表達(dá)式中可以通過 : 后加控制的字符格式化輸出。如上例中的 d 和 f3 即為控制字符。
: 后的控制字符,相當(dāng)于在調(diào)用 ToString 時作為形參控制表達(dá)式的輸出。
上述表達(dá)式等同于:
Debug.Log("On " + date.ToString("d") + ", value is " + value.ToString("f3"));
控制內(nèi)插表達(dá)式的對齊方式
在內(nèi)插表達(dá)式中的個表達(dá)式中可以通過 , 后加數(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);
輸出結(jié)果為:
|Item | Quantity|
|hammer, ball pein | 14|
|hammer, ball pein a | 18|
|hammer, cross pein | 5|
|screwdriver, Phillips #2 | 14|
其中逗號后的數(shù)字,如果為負(fù)數(shù),則輸出為左對齊,如果為正數(shù)則右對齊。數(shù)字本身表示最少的字符數(shù)。因此如果顯示系統(tǒng)中每個字符的寬度是不相等的話,如 i 和 a 的寬度在某些顯示系統(tǒng)下會有較大差異,則即使控制字符寬度也無法實現(xiàn)對其的效果。
如下為相同輸出結(jié)果在 Unity 的 Console 面板中的展示:

表達(dá)式格式和對齊方式也可以一起設(shè)定,但需要首先設(shè)定對其方式,再設(shè)定格式。如下首先控制了左對齊,且字符數(shù)為 10 個,又設(shè)定輸出格式為當(dāng)前小時數(shù):
Debug.Log($"[{DateTime.Now,-10:HH}]");
結(jié)果為:
[10 ]
內(nèi)插表達(dá)式中使用轉(zhuǎn)義序列
如果要在內(nèi)插表達(dá)式中可以使用轉(zhuǎn)義序列,當(dāng)需要多次使用轉(zhuǎn)義序列時也可使用 原義標(biāo)識符@ 替代。
如下所示,分別使用使用了轉(zhuǎn)義序列和原文標(biāo)識符:
string userName = "wxj";
string stringWithEscapes = $"C:\\Users\\{userName}\\Documents";
string verbatimInterpolated = $@"C:\Users\{userName}\Documents";
Debug.Log(stringWithEscapes);
Debug.Log(verbatimInterpolated);
輸出結(jié)果為:
C:\Users\wxj\Documents
C:\Users\wxj\Documents
C# 8.0 后,$ 與 @ 的先后順序不會造成任何影響。在早期版本中,必須先寫 $ 再寫 @。
在內(nèi)插表達(dá)式中,如果需要輸入 {,則按如下方式處理:
int[] values = new int[] { 1, 2 };
Debug.Log($"Value is {{{values[0]}, {values[1]}}}");
輸出結(jié)果為:
Value is {1, 2}
也可以通過 $@ 的結(jié)合控制換行,如下:
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.
內(nèi)插表達(dá)式中使用 ?: 運算符
因為 : 在內(nèi)插表達(dá)式中用來指定格式,因此當(dāng)使用 ?: 運算符時,必須定義在括號內(nèi)。如下所示:
System.Random random = new System.Random();
for (int i = 0; i != 3; ++i)
{
Debug.Log($"Value is {(random.Next() % 2 == 1 ? "Odd" : "Even")}");
}
輸出結(jié)果為:
Even
Odd
Odd
實現(xiàn)細(xì)節(jié)
根據(jù) $ 的實現(xiàn)方式的不同,編譯器會選擇用不同的方式實現(xiàn)字符串插值。
string.Concat
當(dāng)插值的對象為類型為 string 時,編譯器會選擇使用 string.Concat。
如下代碼:
string name = "meziantou";
string hello = $"Hello {name}!";
編譯器會將其轉(zhuǎn)換為:
string name = "meziantou";
string hello = string.Concat("Hello ", name, "!");
string.Format
如果插值的對象為類型為非 string 時,編譯器會選擇使用 string.Format。
如下代碼:
DateTime now = DateTime.Now;
string str = $"It is {now}";
編譯器會將其轉(zhuǎn)換為:
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}";
編譯器會將其轉(zhuǎn)換為:
object value1 = "Foo";
object value2 = "Bar";
FormattableString str = FormattableStringFactory.Create("Test {0} {1}", new object[] { value1, value2 });
當(dāng)真正需要使用該 string 時,會調(diào)用 FormattableString.ToString 方法,將其轉(zhuǎn)換為 string。
constants(C# 10)
在 C# 10 中,支持將內(nèi)插表達(dá)式的結(jié)果作為常量。如下所示:
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
到此這篇關(guān)于C# $字符串插值的使用的文章就介紹到這了,更多相關(guān)C# $字符串插值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#中使用Dapper進(jìn)行數(shù)據(jù)庫訪問的流程步驟
在C#中,Dapper是一個非常流行的ORM(對象關(guān)系映射)工具,它提供了一個輕量級的方式來訪問數(shù)據(jù)庫,Dapper通過SQL語句與數(shù)據(jù)庫進(jìn)行交互,并將結(jié)果映射到.NET對象中,以下是如何在C#中使用Dapper進(jìn)行數(shù)據(jù)庫訪問的基本步驟,需要的朋友可以參考下2024-12-12
C#用Parallel.Invoke方法盡可能并行執(zhí)行提供的每個線程
本文主要介紹了C#用Parallel.Invoke方法盡可能并行執(zhí)行提供的每個線程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01
C# InitializeComponent()方法案例詳解
這篇文章主要介紹了C# InitializeComponent()方法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08

