为什么要用内插字符串代替string.format
知道为什么要用内插字符串,只有踩过坑的人才能明白,如果你曾今使用string.format超5个以上占位符,那其中的痛苦我想你肯定是能够共鸣的。
一:痛苦经历
先上一段曾今写过的一段代码,大家来体会一下:
LogHelper.WriteLog(string.Format(@"=== Square发送服务中 === 【第四步】 leaflet发送成功。 marketID={0},
marketName={1}, 总共客户:{2}, 成功:{3}人, 失败:{4}人,重复:{5}人,
当前优先级:{6},所属shopID={7}",
leafletEntity.MarketingID, leafletEntity.MarketingName,
leafletEntity.CustomerList.Count,leafletEntity.SuccessCount,
leafletEntity.FailCount, leafletEntity.RepeatCustomerNum,
leafletEntity.Priority, leafletEntity.ShopID));
这里拥有多达8个占位符,当年写这个的时候,会有三个痛点。
1. 占位符不能写错了
比如这里的 {0},{1},{2}.... 不能写成了 {0},{0},{2},造成结果的重复输出。

2. 参数值个数不能多也不能少
比如把最后的leafletEntity.ShopID 参数值给丢了,造成8个占位符,7个参数的现象,这样就会造成系统抛异常。

3. 参数值顺序不能错
参数值个数多了,很难保证顺序没被搞错,比如这里的leafletEntity.FailCount和leafletEntity.RepeatCustomerNum,颠倒为leafletEntity.RepeatCustomerNum和leafletEntity.FailCount,你能一眼看出来吗???

二:解决办法
string.format也是曾今模仿C语言留下来的历史遗留问题,如今C#6.0出来了这个内插字符串完美的解决了这三个问题,简直不要太兴奋,接下来把文章开头处改成内插版。
LogHelper.WriteLog($@"=== Square发送服务中 === 【第四步】 leaflet发送成功。
marketID={leafletEntity.MarketingID},
marketName={leafletEntity.MarketingName},
总共客户:{leafletEntity.CustomerList.Count},
成功:{leafletEntity.SuccessCount}人,
失败:{leafletEntity.FailCount}人,
重复:{leafletEntity.RepeatCustomerNum}人,
当前优先级:{leafletEntity.Priority},
所属shopID={leafletEntity.ShopID}");
内插字符串法仅仅就是在字符串前面加上"$"即可,给点时间大家仔细品味一下,是不是很好的解决了我之前提到的3个痛点。
1. 三目运算符在内插法的使用
很多时候在业务开发中,不能仅仅是填充一个变量,而最好还应该支持一些表达值,如使用最多的三目运算符
<1> 错误使用方式
如果你直接这么写,通过不了狠毒的编译器,比如下面这样。

<2> 正确使用方式
解决方法也能简单,在外围加上一个()即可。

2. 复杂逻辑的内插法使用
如果你有复杂的业务逻辑,建议单独另起一个方法。
class Program
{
static void Main(string[] args)
{
var num = 10;
var info = $"i={GetNum(num)}";
}
public static int GetNum(int num)
{
return num == 10 ? 1 : 2;
}
}
如何你的业务逻辑相对比较简单,可以用内联委托的方式实现。

三:探究原理
接下来探究一下,内插字符串这种语法糖在IL层面到底是个啥玩意,你可以通过ILSpy工具查看IL代码。

从上面的截图来看,其实所谓的“内插字符串”就是string.format,编译器的语法糖而已
注意点:
因为有一个box操作,所以你要当点心,如果Console.WriteLine多次执行会有一定的性能损失,建议提前做好box操作,例如下面这样。
static void Main(string[] args)
{
int i = 1, j = 2, k = 3;
var it = i.ToString();
var jt = j.ToString();
var kt = k.ToString();
for (int m = 0; m < int.MaxValue; m++)
{
Console.WriteLine($"i={it},j={jt},k={kt}");
}
}
好了,本篇就说到这里,希望对你有帮助。
为什么要用内插字符串代替string.format的更多相关文章
- JAVA字符串格式化String.format()的使用
JAVA字符串格式化-String.format()的使用常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprin ...
- JAVA字符串格式化-String.format()的使用 【生成随机数补0操作】
转: JAVA字符串格式化-String.format()的使用 常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的s ...
- JAVA字符串格式化-String.format()的使用
String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重载形式. form ...
- JAVA字符串格式化-String.format()的使用(转)
常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重 ...
- Java字符串格式化String.format常用用法
常规的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重载形 ...
- Java系列: JAVA字符串格式化-String.format()的使用(zz)
常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重 ...
- JAVA字符串格式化-String.format()的使用 (转载)
常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重 ...
- json格式的字符串使用string.Format()方法报错:输入字符串的格式不正确
解决:把大括号转义一下就可以了啊,大括号的转义是两个{{ 结尾是}} 今天看同事写的代码,发现他在使用string.format拼接类似json格式的数据时,大括号多了一对,感觉不对就查了查 ...
- 【转】JAVA字符串格式化-String.format()的使用--不错
原文网址:http://blog.csdn.net/lonely_fireworks/article/details/7962171 常规类型的格式化 String类的format()方法用于创建格式 ...
随机推荐
- nes 红白机模拟器 第5篇 全屏显示
先看一下效果图 放大的原理是使用最初级的算法,直接取对应像素法. /*================================================================= ...
- Python 【绘制图及turtle库的使用】
前言 最近翻到一篇知乎,上面有不少用Python(大多是turtle库)绘制的树图,感觉很漂亮,整理了一下,挑了一些觉得不错的代码分享给大家(这些我都测试过,确实可以生成喔~赶快去试一下吧) one ...
- 痞子衡嵌入式:恩智浦SDK驱动代码风格检查工具预览版
大家好,我是痞子衡,是正经搞技术的痞子. 接上文 <恩智浦SDK驱动代码风格.模板.检查工具> 继续聊,是的,过去的三天里我花了一些时间做了一个基于 PyQt5 的 GUI 工具,可以帮助 ...
- 如何配置 GitHub 为个人的手机图床
PicPlus 是一个手机端的图床上传工具,支持七牛云.阿里云.又拍云等主流图床配置,同时还支持配置 GitHub.码云作为自己的图床,如下所示: 这篇文章主要介绍如何在 PicPlus 中配置 Gi ...
- Asp.Net Core 中IdentityServer4 实战之 Claim详解
一.前言 由于疫情原因,让我开始了以博客的方式来学习和分享技术(持续分享的过程也是自己学习成长的过程),同时也让更多的初学者学习到相关知识,如果我的文章中有分析不到位的地方,还请大家多多指教:以后我会 ...
- Natas23 Writeup(php弱类型)
Natas23: 一个登录页面,查看源码,发现关键代码: if(array_key_exists("passwd",$_REQUEST)){ if(strstr($_REQUEST ...
- idea 新建java类自动补充创建人,创建时间,版本等..
1.先进入 File 2.进入 Editor 找到 File and Code Templates 并点击 3.右侧点击 lncludes 4.第二项 File Header /** * @aut ...
- SpringMvc @Validated注解执行原理
@Validated和@Valid对比 Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303规范,是标准JSR-303的一个变种),j ...
- MySQL笔记(7)-- 事务和实现
一.背景 前面有说到InnoDB是事务型引擎,那什么是事务?事务的特性是什么?它所对应的隔离级别是哪些?是怎么实现的?下面来详细讨论下. 二.事务的理解 事务就是一组原子性的SQL查询,或者说一个独立 ...
- 简单BBS项目开始(一)
1.BBS需求分析和创建ORM 1. 需要哪些表 1. UserInfo 1. username 2. password 3. avatar #头像图片 2. 文章表: title publish_d ...