文字列をさらに変更する場合は StringBuilder を返し、それ以外の場合は文字列を返します。これは API に関する質問です。
効率について。これは詳細のない漠然とした/一般的な質問なので、変更可能か不変かはパフォーマンスよりも重要だと思います。可変性は、API が変更可能なオブジェクトを返すようにする API の問題です。これには文字列の長さは関係ありません。
それは言った。Reflector を使用して StringBuilder.ToString を見ると、次のようになります。
public override string ToString()
{
string stringValue = this.m_StringValue;
if (this.m_currentThread != Thread.InternalGetCurrentThread())
{
return string.InternalCopy(stringValue);
}
if ((2 * stringValue.Length) < stringValue.ArrayLength)
{
return string.InternalCopy(stringValue);
}
stringValue.ClearPostNullChar();
this.m_currentThread = IntPtr.Zero;
return stringValue;
}
コピーが作成されることがわかりますが、StringBuilder で変更するとコピーが作成されます (これが m_currentThread のポイントであると言えます。これは、Append がこれをチェックし、現在のスレッドと一致しない場合はコピーするためです) .
これの終わりは、 StringBuilder を変更しない場合、文字列をコピーせず、長さは効率とは無関係であるということだと思います (その 2 番目の if にヒットしない限り)。
アップデート
System.String は、(値型ではなく) 参照型であることを意味するクラスであるため、「string foo;」基本的にポインタです。(文字列をメソッドに渡すと、コピーではなくポインターが渡されます。) System.String は、mscorlib 内では変更可能ですが、mscorlib の外では不変です。これが、StringBuilder が文字列を操作できる方法です。
そのため、ToString() が呼び出されると、内部の文字列オブジェクトが参照によって返されます。コードが mscorlib にないため、この時点では変更できません。m_currentThread フィールドをゼロに設定すると、StringBuilder でさらに操作を行うと、文字列オブジェクトがコピーされ、ToString() で返された文字列オブジェクトを変更できなくなります。このことを考慮:
StringBuilder sb = new StringBuilder();
sb.Append("Hello ");
string foo = sb.ToString();
sb.Append("World");
string bar = sb.ToString();
StringBuilder がコピーを作成しなかった場合、StringBuilder が変更したため、最後に foo は「Hello World」になります。しかし、コピーを作成したので、foo はまだ "Hello" で、bar は "Hello World" です。
それはリターン/リファレンス全体を明確にしていますか?