[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

时间: 2024-12-28 16:48:45

[C#6] 4-string 插值的相关文章

[C#6] 0-概览

1.新特性图谱 C#6的新特性主要有编译器(“Roslyn”)带来,并不依赖CLR和.NET Framework的升级,我们可以认为这个版本的新语言特性的主要目的为了简化代码书写方式,本质上是一些语法糖(编译器优化). 新特性如下: Using static成员 nameof表达式 string插值 Null 条件运算符 自动属性增强 表达式形式的成员函数 字典初始化器 异常增强 2.参考 C# 6.0 如何简化.阐明并压缩您的代码 New Language Features in C# 6

IDW插值分析

private void IDWpointToRaster() { IFeatureLayer pLayer = axMapControl1.get_Layer(0) as IFeatureLayer; IFeatureLayer pExtentLyr = axMapControl1.get_Layer(1) as IFeatureLayer; IFeatureClass pExtentClass = pExtentLyr.FeatureClass; IFeatureClass pFtClass

【Scala】Scala之String

一.前言 大数据领域的Spark.Kafka.Summingbird等都是由Scala语言编写而成,相比Java而言,Scala更精炼.由于笔者从事大数据相关的工作,所以有必要好好学习Scala语言,之前也学习过,但是没有记录,所以就会忘记,感觉Scala确实比Java方便精炼很多,下面以Scala Cookbook英文版作为参考资料,从头到尾梳理Scala相关知识点,也加深印象.PS:这是在研究Zookeeper源码的间隙中交叉学习,不至于总是看源码太枯燥. 二.String 在Scala的R

PEP 0498 -- Literal String Interpolation 翻译(未完待续)

在Python中支持多种的text字符串格式化.包括%方式,str.format()和string.Template.每种方法都有各自的优势,但也有在实际使用时笨重不便之处.本PEP提出一种新的字符串格式化机制: Literal String Interpolation 文本字符串插值(译注:我勒个去,我记性不好,真的只记住一种).在本PEP中,这样的字符串被称为"f-string",为了表示这种字符串,首字符为f,表示"formatted strings"(格式化

9.18 内存区域 全局变量 线程 插值查找 位域 栈的实现

栈区可以修改默认大小配置: 栈区默认的大小是1M,在vs2013中可以修改. 堆区和栈区的地址区别: 栈是连续的,向上增长,地址越来越小.类似数组. 堆是链接的,向下增长,地址越来越大.类似链表. 栈区   高地址到低地址 堆区   低地址到高地址 #include <stdio.h> #include <stdlib.h> int main() { int a = 1, b = 2; printf("%p,%p\n", &a, &b); //a

[译]字符串插值

简介     从Scala2.10.0开始提供了一种利用现有数据(变量等)创建字符串的方式--字符串插值(String Interprolation). 字符串插值允许用户直接在字符串字面量中嵌入变量引用.下面是一个例子: scala> val name = "Jame" name: String = Jame scala> println(s"Hello,$name") Hello,Jame 在上述的例子中,字面量s"Hello,$name&

Swift之字符串(String)

学习一门新语言怎么能少的了字符串呢.Swift中的String和Objective-C语言中NSString还是区别不小的,Swift中的String又回归了正常状态,使用起来更为方便快捷.本篇博客的主题就是Swift中的字符串类型String,String在Swift中让人省心了不少.今天这篇博客就好好的认识一下Swift中的String. 一.字符串拷贝 在Swift中的字符串拷贝直接可以使用=号来操作,这个等号不是指针之间的赋值这么简单.如果将字符串A的值赋给字符串B,那么A和B的的内存地

swift 中String常用操作

1.  字符串定义 var s = "aaaaaa" // 两个字符串均为空并等价. var emptyString = ""   var anotherEmptyString = String() 字符串字面量可以包含以下特殊字符:转义字符  \0 (空字符).  \\ (反斜线).  \t (水平制表符).  \n (换行符). \r (回车符).  \" (双引号).  \' (单引号). 单字节 Unicode 标量,写成  \xnn ,其中  n

Swift新手教程3-字符串String

原创blog,转载请注明出处 String 在swfit中,String兼容Unicode的方式.用法和C语言类似. 注意 在Cocoa和Cocoa touch中,Swift的String,和Foundation中的NSString是兼容的,全部NSString额API都能够调用String类型 字符串常量 1.含转义字符:比如\n,\t等 2.单字节Unicode标量,\xmm 3.双字节Unicode标量,\ummmm 4.四字节Unicode标量,\Ummmmmmmm 这里的m为十六进制数

(java)有序表查找——折半查找,插值查找,斐波那契查找

有序表查找 /* 主函数 */ public class OrderTableSearch { public static void main(String[] args) { int [] a= {0,1,16,24,35,47,59,62,73,88,99}; System.out.println(FibonacciSearch(a, 10, 88)); System.out.println(InsertKeySearch(a, 10, 88)); System.out.println(Bi