改善C#程序的157个建议(连载1)

发表于:2011-10-12 09:37

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:陆敏技    来源:51Testing软件测试网采编

  第1章 基本语言要素

  如何操作字符串?如何进行转型?什么是克隆?什么是相等型?为什么需要HashCode? 当我们真正开始使用一门语言进行编程时,就会遇到这些问题。这些问题看起来简单,可是我们是否想过:为什么要这样处理,这样做是最好的吗?本章的内容将以这些最基础的要素开篇,给出C#编码中的一些最佳实践,让我们在C#进阶学习的过程中始终朝着正确的方向前进。

  建议1: 正确操作字符串

  字符串应该是所有编程语言中使用最频繁的一种基础数据类型。如果使用不慎,我们就会为一次字符串的操作所带来的额外性能开销而付出代价。本条建议将从两个方面来探讨如何规避这类性能开销:

  确保尽量少的装箱

  避免分配额外的内存空间

  先来介绍第一个方面,请看下面的两行代码:

  • 1.  String str1 = "str1"+ 9;  
  • 2.  String str2 = "str2"+ 9.ToString();
  •   为了清楚这两行代码的执行情况,我们来比较两者生成的IL代码。

      第一行代码对应的IL代码如下:

  • .maxstack  8  
  • IL_0000:  ldstr      "str1"  
  • IL_0005:  ldc.i4.s   9  
  • IL_0007:  box        [mscorlib]System.Int32  
  • IL_000c:  call       string [mscorlib]System.String::Concat(object, object)  
  • IL_0011:  pop  
  • IL_0012:  ret
  •   第二行代码对应的IL代码如下:

  • .maxstack  2  
  • .locals init ([0] int32 CS$0$0000)  
  • IL_0000:  ldstr      "str2"  
  • IL_0005:  ldc.i4.s   9  
  • IL_0007:  stloc.0  
  • IL_0008:  ldloca.s   CS$0$0000  
  • IL_000a:  call       instance string [mscorlib]System.Int32::ToString()  
  • IL_000f:  call       string [mscorlib]System.String::Concat(string, string)  
  • IL_0014:  pop  
  • IL_0015:  ret
  •   可以看出,第一行代码“str1”+ 9在运行时会完成一次装箱行为(IL代码中的box);而第二行代码中的9.ToString()并没有发生装箱行为,它实际调用的是整型的ToString方法。ToString方法的原型为:

  • public override String ToString()  
  • {  
  •     return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);  
  • }
  •   可能有人会问,是不是原型中的Number.FormatInt32方法会发生装箱行为呢?实际上,Number.FormatInt32方法是一个非托管的方法,其原型如下:

  • [MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]  
  •  public static extern string FormatInt32(int value, string format,  
  •     NumberFormatInfo info);
  •   它是通过直接操作内存来完成从int到string的转换,效率要比装箱高很多。所以,在使用其他值引用类型到字符串的转换并完成拼接时,应当避免使用操作符“+”来完成,而应该使用值引用类型提供的ToString方法。

      也许有人还会提出疑问:上文所举的示例中,即使FCL提供的方法没有发生装箱行为,但在其他情况下,FCL方法内部会不会含有装箱的行为呢?答案是:也许会存在。不过,我们这里有一个指导原则:

      在自己编写的代码中,应当尽可能地避免编写不必要的装箱代码。

    31/3123>
    《2023软件测试行业现状调查报告》独家发布~

    关注51Testing

    联系我们

    快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

    法律顾问:上海兰迪律师事务所 项棋律师
    版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
    投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

    沪ICP备05003035号

    沪公网安备 31010102002173号