.NET の初期の頃から、StringBuilder で ToString を呼び出すと、StringBuilder が使用する内部 char バッファーを使用して (返される) 新しい文字列オブジェクトを提供していたことをはっきりと覚えています。このように、StringBuilder を使用して巨大な文字列を構築した場合、ToString を呼び出してコピーする必要はありません。
その際、StringBuilder はバッファーへの追加の変更を防止する必要がありました。これは、バッファーが不変の文字列によって使用されるようになったためです。その結果、StringBuilder は「copy-on-change」に切り替わり、変更を試みると最初に新しいバッファーが作成され、古いバッファーの内容がコピーされてから変更されます。
StringBuilder を使用して文字列を作成し、通常の文字列に変換して破棄するという前提があったと思います。私には合理的な仮定のように思えます。
これが問題です。ドキュメントでこれについての言及が見つかりません。しかし、それが文書化されたことがあるかどうかはわかりません。
そこで、Reflector (.NET 4.0) を使用して ToString の実装を調べたところ、バッファを共有するだけでなく、実際に文字列をコピーしているように思えます。
[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. 私はこの本で の言及さえ見つけました。
私の質問は、この動作は削除されましたか? もしそうなら、誰かが理由を知っていますか?それは私にとって完全に理にかなっていました...