.NET面试题:StringBuilder类型有何作用
在第4.1.1节中,读者了解了System.String的不可修改性,在程序中这样的特性容易产生性能的问题,这就需要SystemBuilder类型的帮助。在.NET的面试中,关于StringBuilder的问题可说是最常见的面试题之一。
  所涉及的知识点
· System.String产生的性能问题
· StringBuilder的设计思想和使用方法
  分析问题
String的性能问题产生于其内容不可修改的特性。当一个字符串对象被修改、插入、连接、截断时,新的字符串对象将被分配,这会影响性能。更加常见的情况是,一个字符串对象的最终生成需要经过一个组装的过程,而在这个组装过程中必将产生很多的临时字符串对象。这些对象在堆上分配,需要垃圾回收器来回收,这些动作都会对程序的性能产生巨大的影响。而事实上,在字符串组装过程中,其临时对象都不是最终需要的,可以说是无必要分配的。
这就产生了对StringBuilder类型的需求。StringBuilder类型的设计思想源于构造器的设计模式。构造器设计模式致力于解决复杂对象的构造问题,而对于字符串对象,正需要这样的构造器来进行组装。StringBuilder类型在最终生成String对象之前,将不会产生任何String对象,这很好地解决了字符串操作的性能问题。代码4-2比较了使用StringBuilder和不使用StringBuilder的性能差异。
代码4-2  使用StringBuilder:UseStringBuilder.cs
namespace NET.MST. Fourth.StringBuilder
{
    class TestStringBuilder
    {
        private const String item = "一个项目";
        private const String split = ";";
        static void Main(string[] args)
        {
            int number = 10000;
            //使用StringBuilder
            long sbStart = DateTime.Now.Ticks;
            UseStringBuilder(number);
            long sbEnd = DateTime.Now.Ticks;
            //不使用StringBuilder
            long nsbStart = DateTime.Now.Ticks;
            NotUseStringBuilder(number);
            long nsbEnd = DateTime.Now.Ticks;
            //打印拼接字符串所花的时间
            Console.WriteLine("使用StringBuilder: " + (sbEnd - sbStart).ToString());
            Console.WriteLine("不使用StringBuilder: " +  (nsbEnd - nsbStart).ToString());
            Console.Read();
        }
        //使用StringBuilder拼接字符串
        static String UseStringBuilder(int number)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            for (int i = 0; i < number; i++)
            {
                sb.Append(item);
                sb.Append(split);
            }
            sb.Remove(sb.Length - 1, 1);
            return sb.ToString();
        }
        //不使用StringBuilder拼接字符串
        static String NotUseStringBuilder(int number)
        {
            String result = "";
            for (int i = 0; i < number; i++)
            {
                result += item;
                result += split;
            }
            return result;
        }
    }
}
如代码4-2所示,使用StringBuilder同样可以操作字符串,这样的操作将不会产生任何的中间字符串变量,程序的结果是使用字符串和不使用字符串的性能比较:
使用StringBuilder: 0
不使用StringBuilder: 5468750
StringBuilder类型内部保留了一个私有的String类型成员,当ToString方法被调用时,这个String类型成员将会被赋值并且返回给调用者。在字符串组装期间,这个字符串会在内存上被修改。StringBuilder不仅仅提供了性能上更加优秀的字符串操作,它还能被用来和非托管代码进行交互。对于非托管的代码,字符串的操作是直接基于内存的,如果使用字符串类型和非托管代码进行操作,那潜在地违反了字符串对象不可变的原则。所以StringBuilder常常被用来和非托管代码进行交互。
  答案
StringBuilder采用构造器设计模式的思想高效地构造一个字符串对象,在构造过程中StringBuilder可以有效避免临时字符串对象的生成。一旦StringBuilder的ToString方法被调用后,最终的字符串就被生成,而随后的操作将导致一个新的字符串对象的分配。因为字符串对象的不可修改特性,StringBuilder还经常被用来和非托管代码交互
 

更多.net电子书,.net面试题,.net教学视频请参考"爱学网izixue"