unity que practices how best c# stringbuilder

c# - que - Recorte los espacios en blanco desde el final de un StringBuilder sin llamar a ToString(). Recorte() y vuelva a una nueva SB



stringbuilder methods in c# (3)

El siguiente es un método de extensión, así que puedes llamarlo así:

sb.TrimEnd();

Además, devuelve la instancia de SB, lo que le permite encadenar otras llamadas ( sb.TrimEnd().AppendLine() ).

public static StringBuilder TrimEnd(this StringBuilder sb) { if (sb == null || sb.Length == 0) return sb; int i = sb.Length - 1; for (; i >= 0; i--) if (!char.IsWhiteSpace(sb[i])) break; if (i < sb.Length - 1) sb.Length = i + 1; return sb; }

Notas:

1) Si es nulo o vacío, devuelve.

2) Si realmente no se necesita Trim, estamos hablando de un tiempo de retorno muy rápido, y probablemente la llamada más costosa sea la única llamada para char.IsWhiteSpace. Por lo tanto, prácticamente no hay gastos para llamar a TrimEnd cuando no es necesario, a diferencia de estos ToString (). Trim () de nuevo a las rutas SB.

3) De lo contrario, lo más costoso, si se necesita recortar, son las múltiples llamadas a char.IsWhiteSpace (se interrumpe en la primera charla que no sea de espacios en blanco). Por supuesto, el bucle itera hacia atrás; si todos son espacios en blanco, terminará con un SB.Length of 0.

4) Si se encontraron espacios en blanco, el índice i se mantiene fuera del bucle, lo que nos permite cortar la Longitud de manera apropiada. En StringBuilder, esto es increíblemente eficaz, simplemente establece un entero de longitud interno (el carácter interno [] se mantiene con la misma longitud interna).

ACTUALIZACIÓN2: vea las excelentes notas de Ryan Emerle de la siguiente manera, que corrigen algunos de mis malentendidos (el funcionamiento interno de SB es un poco más complicado de lo que creía ):

El StringBuilder es técnicamente una lista enlazada de bloques de char [], así que no terminamos en el LOH. El ajuste de la longitud no es técnicamente tan simple como cambiar el índice final porque si se mueve a un fragmento diferente, la Capacidad debe mantenerse, por lo que es posible que deba asignarse un nuevo fragmento. Sin embargo, solo establece la propiedad Longitud al final, por lo que parece una gran solución. Detalles relevantes de Eric Lippert: https://stackoverflow.com/a/6524401/62195

También, vea este bonito artículo sobre la implementación de StringBuilder nueva de .NET 4.0: http://1024strongoxen.blogspot.com/2010/02/net-40-stringbuilder-implementation.html

------- ACTUALIZACIÓN --------

A continuación se ilustra lo que sucede cuando se modifica una longitud de StringBuilder (la única operación real que se realiza aquí en la SB, y solo cuando es necesario):

StringBuilder sb = new StringBuilder("cool /t /r/n "); sb.Capacity.Print(); // 16 sb.Length.Print(); // 11 sb.TrimEnd(); sb.Capacity.Print(); // 16 sb.Length.Print(); // 4

Puede ver que la matriz interna (m_ChunkChars) permanece del mismo tamaño después de cambiar la Longitud, y de hecho, puede ver en el depurador que ni siquiera sobrescribe los caracteres (en este caso, espacios en blanco). Están huérfanos, eso es todo.

¿Cuál es una manera eficiente de recortar espacios en blanco desde el final de un StringBuilder sin llamar a ToString (). Recortar () y volver a un nuevo SB new StringBuilder(sb.ToString().Trim()) .


Puedes probar esto:

StringBuilder b = new StringBuilder(); b.Append("some words"); b.Append(" to test "); int count = 0; for (int i = b.Length - 1; i >= 0; i--) { if (b[i] == '' '') count++; else break; } b.Remove(b.Length - count, count); string result = b.ToString();

Simplemente iterará hasta el final mientras haya espacios en blanco y luego salga del bucle.

O incluso así:

StringBuilder b = new StringBuilder(); b.Append("some words"); b.Append(" to test "); do { if(char.IsWhiteSpace(b[b.Length - 1])) { b.Remove(b.Length - 1,1); } } while(char.IsWhiteSpace(b[b.Length - 1])); string get = b.ToString();


StringBuilder myString = new StringBuilder("This is Trim test "); if (myString[myString.Length - 1].ToString() == " ") { myString = myString.Remove(myString.Length - 1, 1); }