你的位置:首页 > ASP.net教程

[ASP.net教程][C#6] 4


0. 目录

C#6 新增特性目录

1. 老版本的代码

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

通常我们在格式化字符串的时候会使用string的静态方法Format来进行字符串拼接,然后使用{0}...{n}来充当占位符。如果{n}过大,代码的可读性就会急剧下降,C#6引入一个新语法来简化这种书写方式。

2. $"{xxx:}"

我们之间来看新语法:

 1 internal class Person 2 { 3   public string Name { get; set; } 4   public int Age { get; set; } 5  6   public override string ToString() 7   { 8     return $"[name={Name},age={Age}]"; 9   }10 }

新语法采用 $  开头,然后把之前的{n}换成了有意义的表达式,直观且简洁,且在VS2015中会有智能提示。好了,基本用法就是这样,按老习惯,对比下IL代码吧。

老版本的IL:

 1 .method public hidebysig virtual instance string  2     ToString() cil managed 3 { 4  // Code size    33 (0x21) 5  .maxstack 3 6  .locals init ([0] string V_0) 7  IL_0000: nop 8  IL_0001: ldstr   "[name={0},age={1}]" 9  IL_0006: ldarg.010  IL_0007: call    instance string csharp6.Person::get_Name()11  IL_000c: ldarg.012  IL_000d: call    instance int32 csharp6.Person::get_Age()13  IL_0012: box    [mscorlib]System.Int3214  IL_0017: call    string [mscorlib]System.String::Format(string,15                                object,16                                object)17  IL_001c: stloc.018  IL_001d: br.s    IL_001f19  IL_001f: ldloc.020  IL_0020: ret21 } // end of method Person::ToString

新语法的IL:

 1 .method public hidebysig virtual instance string  2     ToString() cil managed 3 { 4  // Code size    33 (0x21) 5  .maxstack 3 6  .locals init ([0] string V_0) 7  IL_0000: nop 8  IL_0001: ldstr   "[name={0},age={1}]" 9  IL_0006: ldarg.010  IL_0007: call    instance string csharp6.Person::get_Name()11  IL_000c: ldarg.012  IL_000d: call    instance int32 csharp6.Person::get_Age()13  IL_0012: box    [mscorlib]System.Int3214  IL_0017: call    string [mscorlib]System.String::Format(string,15                                object,16                                object)17  IL_001c: stloc.018  IL_001d: br.s    IL_001f19  IL_001f: ldloc.020  IL_0020: ret21 } // 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.ref10 IL_00ab: call class [mscorlib]System.FormattableString[mscorlib] System.Runtime.CompilerServices.FormattableStringFactory::Create(string,object[])13 IL_00b0: stloc.s s514 IL_00b2: ldstr   "Hello, {0}"15 IL_00b7: ldc.i4.116 IL_00b8: newarr[mscorlib] System.Object17 IL_00bd: dup18 IL_00be: ldc.i4.019 IL_00bf: ldloc.020 IL_00c0: callvirt instance string csharp6.Person::get_Name()21 IL_00c5: stelem.ref22 IL_00c6: call class [mscorlib]System.FormattableString[mscorlib] System.Runtime.CompilerServices.FormattableStringFactory::Create(string,object[])

4. 参考

Interpolated Strings