c#-string 插值

吾生也有涯,而知也无涯。这篇文章主要讲述c#-string 插值相关的知识,希望能为你提供帮助。
1. 老版本的代码

1 internal class Person
2
3public string Nameget; set;
4public int Ageget; set;
5
6public override string ToString()
7
8return string.Format("[name=0,age=1]", Name, Age);
9
10

通常我们在格式化字符串的时候会使用string的静态方法Format来进行字符串拼接,然后使用0...n来充当占位符。如果n过大,代码的可读性就会急剧下降,C#6引入一个新语法来简化这种书写方式。
2. $"xxx:"
我们之间来看新语法:
1 internal class Person
2
3public string Nameget; set;
4public int Ageget; set;
5
6public override string ToString()
7
8return $"[name=Name,age=Age]";
9
10

新语法采用 $ 开头,然后把之前的n换成了有意义的表达式,直观且简洁,且在VS2015中会有智能提示。好了,基本用法就是这样,按老习惯,对比下IL代码吧。
老版本的IL:
1 .method public hidebysig virtual instance string
2ToString() cil managed
3
4// Code size33 (0x21)
5.maxstack3
6.locals init ([0] string V_0)
7IL_0000:nop
8IL_0001:ldstr"[name=0,age=1]"
9IL_0006:ldarg.0
10IL_0007:callinstance string csharp6.Person::get_Name()
11IL_000c:ldarg.0
12IL_000d:callinstance int32 csharp6.Person::get_Age()
13IL_0012:box[mscorlib]System.Int32
14IL_0017:callstring [mscorlib]System.String::Format(string,
15object,
16object)
17IL_001c:stloc.0
18IL_001d:br.sIL_001f
19IL_001f:ldloc.0
20IL_0020:ret
21// end of method Person::ToString

新语法的IL:
1 .method public hidebysig virtual instance string
2ToString() cil managed
3
4// Code size33 (0x21)
5.maxstack3
6.locals init ([0] string V_0)
7IL_0000:nop
8IL_0001:ldstr"[name=0,age=1]"
9IL_0006:ldarg.0
10IL_0007:callinstance string csharp6.Person::get_Name()
11IL_000c:ldarg.0
12IL_000d:callinstance int32 csharp6.Person::get_Age()
13IL_0012:box[mscorlib]System.Int32
14IL_0017:callstring [mscorlib]System.String::Format(string,
15object,
16object)
17IL_001c:stloc.0
18IL_001d:br.sIL_001f
19IL_001f:ldloc.0
20IL_0020:ret
21// end of method Person::ToString

第一眼看到新版本的IL代码,我还以为我没有重新编译我的代码。C#编译器帮我们转成了老版本的写法而已,一模一样的。。。so,这又是一个语法层面的优化。
3. Example
1 //支持方法调用
2 string s1 = $"person.GetHashCode()";
3 //支持表达式
4 string s2 = $"person.nameof(person.Name) is person?.Name";
5 //支持格式化输出
6 DateTime now = DateTime.Now;
7 string s3 = $"DateTime.Now=now:yyyy-MM-dd HH:mm:ss";
8 //组合表达式和格式化输出
9 string s4 = $"person.Name,2 is person.Age:D2 year(person.Age == 1 ? "" : "s") old.";
10 //支持的隐式类型转换
11 IFormattable s5 = $"Hello, person.Name";
12 FormattableString s6 = $"Hello, person.Name"

新语法支持表达式求值,支持:格式化操作,还支持到IFormattable的隐式转换,编译结果是利用 System.Runtime.CompilerServices.FormattableStringFactory.Create 这个静态方法构造一个 FormattableString 实现的。IL如下:
1 IL_0095:stloc.s s4
2 IL_0097:ldstr"Hello, 0"
3 IL_009c:ldc.i4.1
4 IL_009d:newarr[mscorlib] System.Object
5 IL_00a2:dup
6 IL_00a3:ldc.i4.0
7 IL_00a4:ldloc.0
8 IL_00a5:callvirt instance string csharp6.Person::get_Name()
9 IL_00aa:stelem.ref
10 IL_00ab:call class [mscorlib]System.FormattableString[mscorlib] System.Runtime.CompilerServices.FormattableStringFactory::Create(string,object[])
13 IL_00b0:stloc.s s5
14 IL_00b2:ldstr"Hello, 0"
15 IL_00b7:ldc.i4.1
16 IL_00b8:newarr[mscorlib] System.Object
17 IL_00bd:dup
18 IL_00be:ldc.i4.0
19 IL_00bf:ldloc.0
20 IL_00c0:callvirt instance string csharp6.Person::get_Name()
21 IL_00c5:stelem.ref
22 IL_00c6:call class [mscorlib]System.FormattableString[mscorlib] System.Runtime.CompilerServices.FormattableStringFactory::Create(string,object[])

?
【c#-string 插值】本文地址:??https://www.linuxprobe.com/c-string-insert.html??

    推荐阅读