• [C#6] 4-string 插值


    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.0
    10   IL_0007:  call       instance string csharp6.Person::get_Name()
    11   IL_000c:  ldarg.0
    12   IL_000d:  call       instance int32 csharp6.Person::get_Age()
    13   IL_0012:  box        [mscorlib]System.Int32
    14   IL_0017:  call       string [mscorlib]System.String::Format(string,
    15                                                               object,
    16                                                               object)
    17   IL_001c:  stloc.0
    18   IL_001d:  br.s       IL_001f
    19   IL_001f:  ldloc.0
    20   IL_0020:  ret
    21 } // 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.0
    10   IL_0007:  call       instance string csharp6.Person::get_Name()
    11   IL_000c:  ldarg.0
    12   IL_000d:  call       instance int32 csharp6.Person::get_Age()
    13   IL_0012:  box        [mscorlib]System.Int32
    14   IL_0017:  call       string [mscorlib]System.String::Format(string,
    15                                                               object,
    16                                                               object)
    17   IL_001c:  stloc.0
    18   IL_001d:  br.s       IL_001f
    19   IL_001f:  ldloc.0
    20   IL_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[])

    4. 参考

    Interpolated Strings

  • 相关阅读:
    第二章 Java浮点数精确计算
    第一章 Java代码执行流程
    第九章 JVM调优推荐
    第八章 JVM性能监控与故障处理工具(2)
    基于Redis构建10万+终端级的高性能部标JT808协议的Gps网关服务器(转)
    基于Java Netty框架构建高性能的Jt808协议的GPS服务器(转)
    Netty(七):流数据的传输处理
    Java中的位运算符
    二进制(原码、反码、补码)
    Java数据结构和算法(二):数组
  • 原文地址:https://www.cnblogs.com/linianhui/p/csharp6_string-interpolation.html
Copyright © 2020-2023  润新知