[C#6] 4-string 插值
时间:2022-04-23
本文章向大家介绍[C#6] 4-string 插值,主要内容包括0. 目录、1. 老版本的代码、2. $"{xxx:}"、3. Example、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
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[])
- 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](五)
- 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](六)
- android SDL系列讲解(十三) 播放音乐库 SDL_mixer教程
- android am 命令简单讲解(一)
- 渗透测试专用版Linux:BackBox3.13发布
- android dumpsys 快速入门
- 不容小觑的金融诈骗手段 – 419诈骗
- 新年伊始,微软再遭叙利亚电子军挑衅
- 任天堂3DS游戏机烧录卡蓝屏事件
- android调用dialog.hide()引起的输入事件派发错误问题追踪
- 互联网世界的毒瘤——僵尸网络
- android 游戏移植 (一) (文末有福利) | SDL 西游释厄传调试
- 自制分布式漏洞扫描工具
- [细节剖析]X Windows中一个22年的漏洞
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android实现通用筛选栏
- Android实现关机后数据不会丢失问题
- Canvas 进阶(五)实现图片滤镜效果
- 将IP地址字符串分割成数组
- android监听器实例代码
- (火狐)Selenium WebDriver测试 NotADirectoryError: [WinError 267] 目录名称无效。
- 浅析Android高斯模糊实现方案
- Android 自定义验证码输入框的实例代码(支持粘贴连续性)
- _countof和sizeof
- Flutter适配深色模式的方法(DarkMode)
- RecyclerView+SnapHelper实现无限循环筛选控件
- 详解Android 8.1.0 Service 中 弹出 Dialog的方法
- 短信收发类无错版JustinIO.cs
- Android快速实现无预览拍照功能
- RecyclerView+PagerSnapHelper实现抖音首页翻页的Viewpager效果