[C#6] 4-string 插值
0. 目录
1. 老版本的代码
internal class Person
{
public string Name { get; set; }
public int Age { get; set; } public override string ToString()
{
return string.Format("[name={0},age={1}]", Name, Age);
}
}
通常我们在格式化字符串的时候会使用string的静态方法Format来进行字符串拼接,然后使用{0}...{n}来充当占位符。如果{n}过大,代码的可读性就会急剧下降,C#6引入一个新语法来简化这种书写方式。
2. $"{xxx:}"
我们之间来看新语法:
internal class Person
{
public string Name { get; set; }
public int Age { get; set; } public override string ToString()
{
return $"[name={Name},age={Age}]";
}
}
新语法采用 $ 开头,然后把之前的{n}换成了有意义的表达式,直观且简洁,且在VS2015中会有智能提示。好了,基本用法就是这样,按老习惯,对比下IL代码吧。
老版本的IL:
.method public hidebysig virtual instance string
ToString() cil managed
{
// Code size 33 (0x21)
.maxstack
.locals init ([] string V_0)
IL_0000: nop
IL_0001: ldstr "[name={0},age={1}]"
IL_0006: ldarg.
IL_0007: call instance string csharp6.Person::get_Name()
IL_000c: ldarg.
IL_000d: call instance int32 csharp6.Person::get_Age()
IL_0012: box [mscorlib]System.Int32
IL_0017: call string [mscorlib]System.String::Format(string,
object,
object)
IL_001c: stloc.
IL_001d: br.s IL_001f
IL_001f: ldloc.
IL_0020: ret
} // end of method Person::ToString
新语法的IL:
.method public hidebysig virtual instance string
ToString() cil managed
{
// Code size 33 (0x21)
.maxstack
.locals init ([] string V_0)
IL_0000: nop
IL_0001: ldstr "[name={0},age={1}]"
IL_0006: ldarg.
IL_0007: call instance string csharp6.Person::get_Name()
IL_000c: ldarg.
IL_000d: call instance int32 csharp6.Person::get_Age()
IL_0012: box [mscorlib]System.Int32
IL_0017: call string [mscorlib]System.String::Format(string,
object,
object)
IL_001c: stloc.
IL_001d: br.s IL_001f
IL_001f: ldloc.
IL_0020: ret
} // end of method Person::ToString
第一眼看到新版本的IL代码,我还以为我没有重新编译我的代码。C#编译器帮我们转成了老版本的写法而已,一模一样的。。。so,这又是一个语法层面的优化。
3. Example
//支持方法调用
string s1 = $"{person.GetHashCode()}";
//支持表达式
string s2 = $"person.{nameof(person.Name)} is {person?.Name}";
//支持格式化输出
DateTime now = DateTime.Now;
string s3 = $"DateTime.Now={now:yyyy-MM-dd HH:mm:ss}";
//组合表达式和格式化输出
string s4 = $"{person.Name,2} is {person.Age:D2} year{(person.Age == 1 ? "" : "s")} old.";
//支持的隐式类型转换
IFormattable s5 = $"Hello, {person.Name}";
FormattableString s6 = $"Hello, {person.Name}"
新语法支持表达式求值,支持:格式化操作,还支持到IFormattable的隐式转换,编译结果是利用 System.Runtime.CompilerServices.FormattableStringFactory.Create 这个静态方法构造一个 FormattableString 实现的。IL如下:
IL_0095: stloc.s s4
IL_0097: ldstr "Hello, {0}"
IL_009c: ldc.i4.1
IL_009d: newarr[mscorlib] System.Object
IL_00a2: dup
IL_00a3: ldc.i4.0
IL_00a4: ldloc.0
IL_00a5: callvirt instance string csharp6.Person::get_Name()
IL_00aa: stelem.ref
IL_00ab: call class [mscorlib]System.FormattableString[mscorlib] System.Runtime.CompilerServices.FormattableStringFactory::Create(string,object[])
IL_00b0: stloc.s s5
IL_00b2: ldstr "Hello, {0}"
IL_00b7: ldc.i4.1
IL_00b8: newarr[mscorlib] System.Object
IL_00bd: dup
IL_00be: ldc.i4.0
IL_00bf: ldloc.0
IL_00c0: callvirt instance string csharp6.Person::get_Name()
IL_00c5: stelem.ref
IL_00c6: call class [mscorlib]System.FormattableString[mscorlib] System.Runtime.CompilerServices.FormattableStringFactory::Create(string,object[])
4. 参考
[C#6] 4-string 插值的更多相关文章
- C#6新特性,让你的代码更干净
前言 前几天看一个朋友的博客时,看他用到了C#6的特性,而6出来这么长时间还没有正儿八经看过它,今儿专门看了下新特性,说白了也不过是语法糖而已.但是用起来确实能让你的代码更加干净些.Let's try ...
- [C#6] 0-概览
1. C#6 新特性图谱 C#6的新特性主要由编译器(“Roslyn”)带来,并不依赖CLR和.NET Framework的升级,我们可以认为这个版本的新语言特性的主要目的为了简化代码书写方式,让我们 ...
- JVM 平台上的各种语言的开发指南
JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...
- Groovy中String转换Gstring用于动态插值
知识点是Groovy中的模板引擎 GStringTemplateEngine 第一个例子: def binding = [ firstname : "Grace", lastnam ...
- 窥探Swift之字符串(String)
之前总结过Objective-C中的字符串<Objective-C精选字符串处理方法>,学习一门新语言怎么能少的了字符串呢.Swift中的String和Objective-C语言中NSSt ...
- 用JAVA实现插值查询的方法(算近似值,区间求法)
插值查询:如果有这样一张表,有一列叫水位,有一列叫库容,比如下面的图. 我现在想做这么一件事情:对于这个测站而言,当我输入某一个水位或者库容的时候,想要查询到对应的水位或者库容呢? 而这个值不一定是存 ...
- 关于IDW空间插值
空间插值一般都会用到IInterPolationOP接口等 首先是通过图层的名称获取图层的方法: private ILayer GetLayerByName(string name) { ...
- 你需要知道的Sass插值
你也许会不时地写写 Sass 玩玩,你也会很享受它带给你各种便利.但还有一件事,你并不一定完全了解:插值 (interpolation) - 将一个占位符,替换成一个值.好了,你们都很幸运,因为今天我 ...
- iOS -Swift 3.0 -String(字符串常规用法)
// // ViewController.swift // Swift-String // // Created by luorende on 16/9/10. // Copyright © 2016 ...
- iOS - Swift String 字符串
前言 public struct String public class NSString : NSObject, NSCopying, NSMutableCopying, NSSecureCodin ...
随机推荐
- js 根据屏幕大小调用不同的css文件
原因:屏幕大小不一样,网站看起来总觉得怪怪的,所以,针对不同大小的屏幕,写了不同的css,写完了,要解决的问题就是:怎么根据屏幕的大小来引用不同的CSS,下面就是解决方法了. 解决方法:首先,在hea ...
- IDDD 实现领域驱动设计-架构之经典分层
上一篇:<IDDD 实现领域驱动设计-上下文映射图及其相关概念> 在<实现领域驱动设计>书中,分层的概念作者讲述的很少,也就几页的内容,但对于我来说,有很多的感触需要诉说.之前 ...
- DDD 领域驱动设计-“臆想”中的实体和值对象
其他博文: DDD 领域驱动设计-三个问题思考实体和值对象 DDD 领域驱动设计-三个问题思考实体和值对象(续) 以下内容属于博主"臆想",如有不当,请别当真. 扯淡开始: 诺兰的 ...
- canvas学习和面向对象(二)
Canvas 学习(二) 上一篇Canvas 学习(一)中我是用canvas绘制了一些基本和组合的图形. 现在开始绘制图片和动画帧,以及面向对象的升级版本. 还是一样,看代码,所有的代码都托管在git ...
- js 对Array的补充
Array.form的用法 1.可以将各种值转为真正的数组,并且还提供map功能.这实际上意味着,只要有一个原始的数据结构,你就可以先对它的值进行处理,然后转成规范的数组结构,进而就可以使用数量众多的 ...
- 异步Promise实现
简介 异步回调的书写往往打乱了正常流的书写方式,在ECMAScript 6中实现了标准的Promise API,旨在 解决控制回调流程的问题. 简单的实现了Promise API: (function ...
- Oracle同义词+dblink的实际应用
Oracle同义词+dblink的实际应用 业务需求:原数据库(10.2.0.4.0),新数据库(11.2.0.3) 由于程序的需求原因,现在需要把新库上的某个用户直接映射到老库用户下: 1. 备份原 ...
- 4.Java网络编程之TCP/UDP
常见传输协议: UDP , TCP UDP协议: 特点: 1.将数据及源和目的封装成数据包中,不需要建立连接 2.每个数据包的大小限制在64K内 ...
- Sql Server函数全解(一)字符串函数
字符串函数用于对字符和二进制字符进行各种操作 1.ASCII()函数 ASCII(character_expression)函数用于返回字符串表达式中最左侧的ASCII代码值.参数character ...
- WCF学习系列三--【WCF Interview Questions – Part 3 翻译系列】
http://www.topwcftutorials.net/2012/10/wcf-faqs-part3.html WCF Interview Questions – Part 3 This WCF ...