有很多朋友提出,StringBuilder中Capacity的值是成倍扩充的,但是我今天使用StringBuilder的时候发现了在某些情况下其Capacity不是成倍扩充的,望高手能给出解释,谢谢!下面是具体代码及执行结果
System.Text.StringBuilder sb = new System.Text.StringBuilder();
Console.WriteLine("Capacity:" + sb.Capacity);
Console.WriteLine("Length:" + sb.Length);
sb.Append('1',16);
Console.WriteLine("Capacity:" + sb.Capacity);
Console.WriteLine("Length:" + sb.Length);
sb.Append('2',32);
Console.WriteLine("Capacity:" + sb.Capacity);
Console.WriteLine("Length:" + sb.Length);
sb.Append('3',64);
Console.WriteLine("Capacity:" + sb.Capacity);
Console.WriteLine("Length:" + sb.Length);
try
{
sb.Remove(0,sb.Length);
Console.WriteLine("Capacity:" + sb.Capacity);
Console.WriteLine("Length:" + sb.Length);
sb.Capacity = 1;
sb.Append('a',2);
Console.WriteLine("Capacity:" + sb.Capacity);
Console.WriteLine("Length:" + sb.Length);
sb.Append('b',4);
Console.WriteLine("Capacity:" + sb.Capacity);
Console.WriteLine("Length:" + sb.Length);
sb.Append('c',6);
Console.WriteLine("Capacity:" + sb.Capacity);
Console.WriteLine("Length:" + sb.Length);
}
catch(ArgumentOutOfRangeException e)
{
Console.WriteLine(e.Message);
return;
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
return;
}
Console.ReadLine();
其执行结果是:
Capacity:16     Length:0    
Capacity:16     Length:16    
Capacity:49     Length:48    
Capacity:113     Length:112
Capacity:113     Length:0    
Capacity:3      Length:2    
Capacity:7     Length:6
Capacity:14     Length:12

解决方案 »

  1.   

    测试代码有问题??
    这是stringbuilder添加元素所进行的操作private string GetNewString(string currentString, int requiredLength)
    {
          requiredLength++;
          if (requiredLength < 0)
          {
                throw new OutOfMemoryException();
          }
          if (requiredLength > this.m_MaxCapacity)
          {
                throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"), "requiredLength");
          }
          int num1 = currentString.Capacity * 2;//注意这里
          if (num1 < requiredLength)//还有这里
          {
                num1 = requiredLength;
          }
          if (num1 > this.m_MaxCapacity)
          {
                num1 = this.m_MaxCapacity;
          }
          if (num1 <= 0)
          {
                throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
          }
          return string.GetStringForStringBuilder(currentString, num1);
    }
      

  2.   

    但是Capacity的大小为什么有113这些呢
      

  3.   


    你最好用反编译软件看看StringBuilder的实现,上面那些代码就是我用工具反编译的的,
    因为代码比较多一些,我不好往上全贴,简单的说就是stringbuilder最后一位需要加一个'\0'来代表字符串结束。
    internal unsafe void AppendInPlace(char value, int repeatCount, int currentLength)
    {
          int num1 = currentLength + repeatCount;
          fixed (char* chRef1 = &this.m_firstChar)
          {
                int num2 = currentLength;
                while (num2 < num1)
                {
                      chRef1[num2] = value;
                      num2++;
                }
                chRef1[num2] = '\0';//这里      }
          this.m_stringLength = num1;
    }