Devuelve StringBuilder si vas a modificar aún más la cadena; de lo contrario, devuelve la cadena. Esta es una pregunta API.
En cuanto a la eficiencia. Dado que esta es una pregunta vaga/general sin ningún detalle, entonces creo que mutable vs. inmutable es más importante que el rendimiento. La capacidad de mutación es un problema de API que permite que su API devuelva objetos modificables. La longitud de la cadena es irrelevante para esto.
Dicho eso. Si nos fijamos en StringBuilder.ToString con reflector:
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;
}
se puede ver que se puede hacer una copia, pero si lo modifica con el StringBuilder continuación, se hará una copia a continuación (esto es lo que puedo decir el punto de m_currentThread es porque Append lo verifica y lo copiará si no coincide con el hilo actual).
Supongo que el final de esto es que si no modifica StringBuilder, entonces no copia la cadena y la longitud es irrelevante para la eficiencia (a menos que haga clic en 2nd si).
ACTUALIZACIÓN
System.String es una clase que significa que es un tipo de referencia (a diferencia de tipo de valor) de manera "foo cadena;" es esencialmente un puntero. (Cuando pasa una cadena a un método, pasa el puntero, no una copia.) System.String es mutable dentro de mscorlib pero inmutable fuera de él, que es cómo StringBuilder puede manipular una cadena.
Así que cuando se llama a ToString() devuelve su objeto de cadena interno por referencia. En este punto, no puede modificarlo porque su código no está en mscorlib. Al establecer el campo m_currentThread en cero, cualquier operación adicional en StringBuilder hará que copie el objeto de cadena para que se pueda modificar y no modifique el objeto de cadena que devolvió en ToString(). Considere esto:
StringBuilder sb = new StringBuilder();
sb.Append("Hello ");
string foo = sb.ToString();
sb.Append("World");
string bar = sb.ToString();
Si StringBuilder no hizo una copia a continuación, en el extremo foo sería "Hola mundo" debido a que el StringBuilder lo modificó. Pero como hizo una copia, foo sigue siendo solo "Hello" y la barra es "Hello World".
¿Eso aclara todo el asunto de devolución/referencia?
@SkippyFire pregunta por la eficiencia. –
-1. Si va a modificar aún más la cadena, debe modificarse aún más dentro del método. ¿Qué ocurre si se llama a este método desde varios lugares y la lógica de manipulación de cadenas cambia? No sería bueno actualizar la lógica en varios lugares –
Nick, estás dividiendo los pelos. Si se trata de una clase y un método privado, puede pasar StringBuilder a muchos métodos para construir la cadena final. Podría hacer lo mismo donde cada método devuelve una cadena y los concatena. SkippyFire no fue específico en absoluto en cómo se usa esto. Es bastante simple: si necesita mutable, entonces devuelva mutable, si no necesita mutable, entonces no devuelva mutable. –