第1章 基本语言要素
如何操作字符串?如何进行转型?什么是克隆?什么是相等型?为什么需要HashCode? 当我们真正开始使用一门语言进行编程时,就会遇到这些问题。这些问题看起来简单,可是我们是否想过:为什么要这样处理,这样做是最好的吗?本章的内容将以这些最基础的要素开篇,给出C#编码中的一些最佳实践,让我们在C#进阶学习的过程中始终朝着正确的方向前进。
建议1: 正确操作字符串
字符串应该是所有编程语言中使用最频繁的一种基础数据类型。如果使用不慎,我们就会为一次字符串的操作所带来的额外性能开销而付出代价。本条建议将从两个方面来探讨如何规避这类性能开销:
确保尽量少的装箱
避免分配额外的内存空间
先来介绍第一个方面,请看下面的两行代码:
为了清楚这两行代码的执行情况,我们来比较两者生成的IL代码。
第一行代码对应的IL代码如下:
第二行代码对应的IL代码如下:
可以看出,第一行代码“str1”+ 9在运行时会完成一次装箱行为(IL代码中的box);而第二行代码中的9.ToString()并没有发生装箱行为,它实际调用的是整型的ToString方法。ToString方法的原型为:
可能有人会问,是不是原型中的Number.FormatInt32方法会发生装箱行为呢?实际上,Number.FormatInt32方法是一个非托管的方法,其原型如下:
它是通过直接操作内存来完成从int到string的转换,效率要比装箱高很多。所以,在使用其他值引用类型到字符串的转换并完成拼接时,应当避免使用操作符“+”来完成,而应该使用值引用类型提供的ToString方法。
也许有人还会提出疑问:上文所举的示例中,即使FCL提供的方法没有发生装箱行为,但在其他情况下,FCL方法内部会不会含有装箱的行为呢?答案是:也许会存在。不过,我们这里有一个指导原则:
在自己编写的代码中,应当尽可能地避免编写不必要的装箱代码。