Я отчетливо помню из первых дней .NET, что вызов ToString в StringBuilder используется для предоставления нового строкового объекта (который будет возвращен) с внутренним буфером char, используемым StringBuilder. Таким образом, если вы построили огромную строку с помощью StringBuilder, вызов ToString не должен был ее копировать.
При этом StringBuilder должен был предотвратить любые дополнительные изменения в буфере, потому что теперь он использовался неизменяемой строкой. В результате StringBuilder переключится на "copy-on-change", сделанный там, где любые попытки изменения сначала создадут новый буфер, скопируют содержимое старого буфера и только затем изменят его.
Я думаю, что предположение состояло в том, что StringBuilder будет использоваться для построения строки, затем преобразовывается в обычную строку и отбрасывается. Мне кажется разумным предположением.
Теперь вот что. Я не могу найти упоминания об этом в документации. Но я не уверен, что это когда-либо документировалось.
Итак, я посмотрел на реализацию ToString с использованием Reflector (.NET 4.0), и мне кажется, что он фактически копирует строку, а не просто передает буфер:
[SecuritySafeCritical]
public override unsafe string ToString()
{
string str = string.FastAllocateString(this.Length);
StringBuilder chunkPrevious = this;
fixed (char* str2 = ((char*) str))
{
char* chPtr = str2;
do
{
if (chunkPrevious.m_ChunkLength > 0)
{
char[] chunkChars = chunkPrevious.m_ChunkChars;
int chunkOffset = chunkPrevious.m_ChunkOffset;
int chunkLength = chunkPrevious.m_ChunkLength;
if ((((ulong) (chunkLength + chunkOffset)) > str.Length) || (chunkLength > chunkChars.Length))
{
throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
fixed (char* chRef = chunkChars)
{
string.wstrcpy(chPtr + chunkOffset, chRef, chunkLength);
}
}
chunkPrevious = chunkPrevious.m_ChunkPrevious;
}
while (chunkPrevious != null);
}
return str;
}
Теперь, как я уже говорил, я отчетливо помню, как это было в первые дни, если .NET. Я даже нашел упоминание в этом book.
Мой вопрос: было ли это поведение отменено? Если да, то кто-нибудь знает почему? Это имело для меня смысл...