2017-09-13 63 views
2

StringBuilder在ToString調用時緩存字符串嗎?例如,這將創建兩個不同的內存串,或只使用一個:是否StringBuilder在ToString()調用時緩存結果字符串?

var sb = new StringBuilder(); 
sb.Append("foo"); 
sb.Append("bar"); 

var str1 = sb.ToString(); 
var str2 = sb.ToString(); 

它會緩存連續讀取操作自己的結果呢?

+0

嗯創建,是什麼不清楚的嗎?這是簡單的緩存問題。 – eocron

+3

但是爲什麼問,只需檢查'ReferenceEquals(str1,str2)' –

+0

您還可以在類https://referencesource.microsoft.com/#mscorlib/system/text/stringbuilder中檢查「ToString」的實現。 cs – Pikoh

回答

5

source code尋找的StringBuilderToString()。答案是否

[System.Security.SecuritySafeCritical] // auto-generated 
    public override String ToString() { 
     Contract.Ensures(Contract.Result<String>() != null); 

     VerifyClassInvariant(); 

     if (Length == 0) 
      return String.Empty; 

     string ret = string.FastAllocateString(Length); 
     StringBuilder chunk = this; 
     unsafe { 
      fixed (char* destinationPtr = ret) 
      { 
       do 
       { 
        if (chunk.m_ChunkLength > 0) 
        { 
         // Copy these into local variables so that they are stable even in the presence of ----s (hackers might do this) 
         char[] sourceArray = chunk.m_ChunkChars; 
         int chunkOffset = chunk.m_ChunkOffset; 
         int chunkLength = chunk.m_ChunkLength; 

         // Check that we will not overrun our boundaries. 
         if ((uint)(chunkLength + chunkOffset) <= ret.Length && (uint)chunkLength <= (uint)sourceArray.Length) 
         { 
          fixed (char* sourcePtr = sourceArray) 
           string.wstrcpy(destinationPtr + chunkOffset, sourcePtr, chunkLength); 
         } 
         else 
         { 
          throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index")); 
         } 
        } 
        chunk = chunk.m_ChunkPrevious; 
       } while (chunk != null); 
      } 
     } 
     return ret; 
0

我想是因爲它的將是兩個可變和你在字符串生成器調用toString

var str1 = sb.ToString();//one variable and new string 
var str2 = sb.ToString();//two variable and new string 

我的意思是說每一次新的字符串將會被創建。

示例代碼:

static void Main(string[] args) 
     { 

      var sb = new StringBuilder(); 
      sb.Append("foo"); 
      sb.Append("bar"); 

      var str1 = sb.ToString(); 
      var str2 = sb.ToString(); 

      Console.WriteLine(str1); 
      Console.WriteLine(str2); 
      str1 += " str1"; 
      str2 += " str2"; 

      Console.WriteLine(str1); 
      Console.WriteLine(str2); 

      Console.ReadLine(); 
     } 

輸出:

foobar 
foobar 
foobar str1 
foobar str2 
2

完全相同實施的StringBuilder類是這樣的:

public override String ToString() 
{ 
    Contract.Ensures(Contract.Result<String>() != null); 

    VerifyClassInvariant(); 

    if (Length == 0) 
     return String.Empty; 

    string ret = string.FastAllocateString(Length); 
    StringBuilder chunk = this; 
    unsafe 
    { 
     fixed (char* destinationPtr = ret) 
     { 
      do 
      { 
       if (chunk.m_ChunkLength > 0) 
       { 
        // Copy these into local variables so that they are stable even in the presence of ----s (hackers might do this) 
        char[] sourceArray = chunk.m_ChunkChars; 
        int chunkOffset = chunk.m_ChunkOffset; 
        int chunkLength = chunk.m_ChunkLength; 

        // Check that we will not overrun our boundaries. 
        if ((uint)(chunkLength + chunkOffset) <= ret.Length && (uint)chunkLength <= (uint)sourceArray.Length) 
        { 
         fixed (char* sourcePtr = sourceArray) 
          string.wstrcpy(destinationPtr + chunkOffset, sourcePtr, chunkLength); 
        } 
        else 
        { 
         throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index")); 
        } 
       } 
       chunk = chunk.m_ChunkPrevious; 
      } while (chunk != null); 
     } 
    } 
    return ret; 
} 

,正如你可以看到它回報名爲RET是在這個方法內聲明的字符串....不被任何緩存...

0

str1和str2是「foo」和「bar」組合的2個單獨實例。當你第二次調用ToSring()時,第一次調用的時候會做同樣的事情,但這兩個調用之間沒有任何緩存,儘管我認爲它們可以。但是你也可以做str2 = str1。在這兩種情況下,str1和str2在不同的內存區域中都是2個獨立的不可變字符串。

-1

兩個不同的字符串將在存儲在您的情況

var str1 = sb.ToString(); // 1st string  
var str2 = sb.ToString(); // 2nd string 
相關問題