知道为什么要用内插字符串,只有踩过坑的人才能明白,如果你曾今使用string.format超5个以上占位符,那其中的痛苦我想你肯定是能够共鸣的。

一:痛苦经历

先上一段曾今写过的一段代码,大家来体会一下:

  1. LogHelper.WriteLog(string.Format(@"=== Square发送服务中 === 【第四步】 leaflet发送成功。 marketID={0},
  2. marketName={1}, 总共客户:{2}, 成功:{3}人, 失败:{4}人,重复:{5}人,
  3. 当前优先级:{6},所属shopID={7}",
  4. leafletEntity.MarketingID, leafletEntity.MarketingName,
  5. leafletEntity.CustomerList.Count,leafletEntity.SuccessCount,
  6. leafletEntity.FailCount, leafletEntity.RepeatCustomerNum,
  7. 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出来了这个内插字符串完美的解决了这三个问题,简直不要太兴奋,接下来把文章开头处改成内插版。

  1. LogHelper.WriteLog($@"=== Square发送服务中 === 【第四步】 leaflet发送成功。
  2. marketID={leafletEntity.MarketingID},
  3. marketName={leafletEntity.MarketingName},
  4. 总共客户:{leafletEntity.CustomerList.Count},
  5. 成功:{leafletEntity.SuccessCount}人,
  6. 失败:{leafletEntity.FailCount}人,
  7. 重复:{leafletEntity.RepeatCustomerNum}人,
  8. 当前优先级:{leafletEntity.Priority},
  9. 所属shopID={leafletEntity.ShopID}");

内插字符串法仅仅就是在字符串前面加上"$"即可,给点时间大家仔细品味一下,是不是很好的解决了我之前提到的3个痛点。

1. 三目运算符在内插法的使用

很多时候在业务开发中,不能仅仅是填充一个变量,而最好还应该支持一些表达值,如使用最多的三目运算符

<1> 错误使用方式

如果你直接这么写,通过不了狠毒的编译器,比如下面这样。

<2> 正确使用方式

解决方法也能简单,在外围加上一个()即可。

2. 复杂逻辑的内插法使用

如果你有复杂的业务逻辑,建议单独另起一个方法。

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. var num = 10;
  6. var info = $"i={GetNum(num)}";
  7. }
  8. public static int GetNum(int num)
  9. {
  10. return num == 10 ? 1 : 2;
  11. }
  12. }

如何你的业务逻辑相对比较简单,可以用内联委托的方式实现。

三:探究原理

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

从上面的截图来看,其实所谓的“内插字符串”就是string.format,编译器的语法糖而已

注意点:

因为有一个box操作,所以你要当点心,如果Console.WriteLine多次执行会有一定的性能损失,建议提前做好box操作,例如下面这样。

  1. static void Main(string[] args)
  2. {
  3. int i = 1, j = 2, k = 3;
  4. var it = i.ToString();
  5. var jt = j.ToString();
  6. var kt = k.ToString();
  7. for (int m = 0; m < int.MaxValue; m++)
  8. {
  9. Console.WriteLine($"i={it},j={jt},k={kt}");
  10. }
  11. }

好了,本篇就说到这里,希望对你有帮助。

为什么要用内插字符串代替string.format的更多相关文章

  1. JAVA字符串格式化String.format()的使用

    JAVA字符串格式化-String.format()的使用常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprin ...

  2. JAVA字符串格式化-String.format()的使用 【生成随机数补0操作】

    转: JAVA字符串格式化-String.format()的使用 常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的s ...

  3. JAVA字符串格式化-String.format()的使用

    String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重载形式. form ...

  4. JAVA字符串格式化-String.format()的使用(转)

    常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重 ...

  5. Java字符串格式化String.format常用用法

    常规的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重载形 ...

  6. Java系列: JAVA字符串格式化-String.format()的使用(zz)

    常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重 ...

  7. JAVA字符串格式化-String.format()的使用 (转载)

    常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重 ...

  8. json格式的字符串使用string.Format()方法报错:输入字符串的格式不正确

    解决:把大括号转义一下就可以了啊,大括号的转义是两个{{  结尾是}}     今天看同事写的代码,发现他在使用string.format拼接类似json格式的数据时,大括号多了一对,感觉不对就查了查 ...

  9. 【转】JAVA字符串格式化-String.format()的使用--不错

    原文网址:http://blog.csdn.net/lonely_fireworks/article/details/7962171 常规类型的格式化 String类的format()方法用于创建格式 ...

随机推荐

  1. 用libvlc 播放指定缓冲区中的视频流

    有时候,我们需要播放别的模块传输过来的视频流,VLC提供了这样的机制,但一般很少这样用,下面的例子实现了这样的功能. 其中用到一个关键的模块 imem.  vlc提供多种创建媒体的方式,如要从指定缓存 ...

  2. ggplot2(9) 数据操作

    9.1 plyr包简介 ddply {plyr}: Split data frame, apply function, and return results in a data frame. ddpl ...

  3. C++ for循环练习

    #include <stdio.h> //题目:现有公鸡5元一只,母鸡3元一只,小鸡1元3只(小鸡不能单买 最少3只起卖),此时顾客有100元,请问有多少种购买方案. int main() ...

  4. vue中nextTick的使用场景

    https://blog.csdn.net/bingqise5193/article/details/100212278

  5. ipadmini iOS8.4.1系统精简

    主要是删除一些系统自带的应用.语言,以及关闭不需要的进程. 精简之后运行流畅性还是能看得出有所提升的.(流畅的玩点游戏还是可行的) 文件的操作可以用Filza.iFile,也可以用爱思助手,但是爱思助 ...

  6. 移动端Rem适配(基于vue-cli3 ,ui框架用的是vant-ui)

    介绍postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 remlib-flexible 用于设置 rem 基准值 1.安装lib-flexible(用于设置 rem 基准值 ...

  7. 如何查看子线程中的GC Alloc

    1)如何查看子线程中的GC Alloc2)Build时,提示安卓NDK异常3)如何获得ParticleSystem产生的三角形数量4)关于图片通道的问题5)GPUSkinning导致模型动画不平滑 M ...

  8. 《Python学习手册 第五版》 -第17章 作用域

    上一章的是函数的基础,因为函数在运用过程中,是可以嵌套的,函数中是会涉及到变量的,为了明确各自变量的使用范围,系统是有一套规则或者原则的,这就是作用域的概念 本章重点内容 1.作用域:作用域的概念 2 ...

  9. 15. 获取类路径下文件对应的输入流(inputStream)方式

    //获取 inputStream 方式一Resource resource = new ClassPathResource("excel/template/test.xlsx"); ...

  10. NIO的原理和文件读入读出及图片拷贝的使用

    1.NIO的简介        java.nio 全称 java non-blocking IO 是jdk1.4之后出现的 New IO        为所有的原始类型(boolean除外)提供了缓存 ...