使用StringBuilder先搞懂Capacity

  • 1615
  • 0
  • C#
  • 2013-08-21

摘要:使用StringBuilder的注意事項

很多使用者常常使用StringBuilder類別來取代字串的串接,但是StringBuilder本身

 

的實作方式是以陣列方式來存取字串,預設的Capacity是16,當使用者超出個這個量時,

 

它會在自行擴增,可是就像陣列一樣,若你常常重新定義陣列大小,實際上是會影響效能的,

 

因此這時候使用Capacity這個屬性就很重要了,它提供了事先定義StringBuilder的大小。

 

以下展示StringBulder原始碼如何擴展它的大小 :

 

System.Text.StringBuilder 原始碼

 


[SecuritySafeCritical]
internal unsafe StringBuilder Append(char* value, int valueCount)
{
    int num = valueCount + this.m_ChunkLength;
    if (num <= this.m_ChunkChars.Length)
    {
        StringBuilder.ThreadSafeCopy(value, this.m_ChunkChars, this.m_ChunkLength, valueCount);
        this.m_ChunkLength = num;
    }
    else
    {
   // m_ChunkChars.Length  = capacity      m_ChunkLength  =  stringbuilder.length
        int num2 = this.m_ChunkChars.Length - this.m_ChunkLength;
        if (num2 > 0)
        {
            StringBuilder.ThreadSafeCopy(value, this.m_ChunkChars, this.m_ChunkLength, num2);
            this.m_ChunkLength = this.m_ChunkChars.Length;
        }
        int num3 = valueCount - num2;
        this.ExpandByABlock(num3);
        StringBuilder.ThreadSafeCopy(value + (IntPtr)num2, this.m_ChunkChars, 0, num3);
        this.m_ChunkLength = num3;
    }
    return this;
}

 

若超過預設的capacity,則藉由以下ExpandByABlock擴展



private void ExpandByABlock(int minBlockCharCount)
{
    if (minBlockCharCount + this.Length > this.m_MaxCapacity)
    {
        throw new ArgumentOutOfRangeException("requiredLength", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
    }
    int num = Math.Max(minBlockCharCount, Math.Min(this.Length, 8000));
    this.m_ChunkPrevious = new StringBuilder(this);
    this.m_ChunkOffset += this.m_ChunkLength;
    this.m_ChunkLength = 0;
    if (this.m_ChunkOffset + num < num)
    {
        this.m_ChunkChars = null;
        throw new OutOfMemoryException();
    }
    this.m_ChunkChars = new char[num];
}

 

 

資料來源 :

MSDN StringBuilder