2017-09-13 67 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 
相关问题