c# - best - stringbuilder example
¿Cuándo utilizas StringBuilder.AppendLine/string.Format vs. StringBuilder.AppendFormat? (7)
Apareció una pregunta reciente sobre el uso de String.Format (). Parte de mi respuesta incluía una sugerencia para usar StringBuilder.AppendLine (string.Format (...)). Jon Skeet sugirió que este era un mal ejemplo y propuso usar una combinación de AppendLine y AppendFormat.
Se me ocurrió que nunca me había acostumbrado a un enfoque "preferido" para usar estos métodos. Creo que podría comenzar a usar algo como lo siguiente, pero estoy interesado en saber qué otras personas usan como una "mejor práctica":
sbuilder.AppendFormat("{0} line", "First").AppendLine();
sbuilder.AppendFormat("{0} line", "Second").AppendLine();
// as opposed to:
sbuilder.AppendLine( String.Format( "{0} line", "First"));
sbuilder.AppendLine( String.Format( "{0} line", "Second"));
¿Es simplemente horrible simplemente usar
sbuilder.AppendFormat("{0} line/n", first);
? Quiero decir, sé que no es independiente de la plataforma o lo que sea, pero en 9 de cada 10 casos hace el trabajo.
AppendFormat () es mucho más legible que AppendLine (String.Format ())
Si el rendimiento es importante, trate de evitar AppendFormat () por completo. Use múltiples llamadas Append () o AppendLine () en su lugar. Esto hace que su código sea más grande y menos legible, pero es más rápido porque no se debe realizar un análisis de cadenas. El análisis de cadenas es más lento de lo que imagina.
Generalmente uso:
sbuilder.AppendFormat("{0} line", "First");
sbuilder.AppendLine();
sbuilder.AppendFormat("{0} line", "Second");
sbuilder.AppendLine();
A menos que el rendimiento sea crítico, en cuyo caso usaría:
sbuilder.Append("First");
sbuilder.AppendLine(" line");
sbuilder.Append("Second");
sbuilder.AppendLine(" line");
(Por supuesto, esto tendría más sentido si "Primero" y "Segundo" no fueran literales de cadena)
String.format crea un objeto StringBuilder internamente. Haciendo
sbuilder.AppendLine( String.Format( "{0} line", "First"));
Se crea una instancia adicional de generador de cadenas, con toda su sobrecarga.
Reflector en mscorlib, Commonlauageruntimelibary, System.String.Format
public static string Format(IFormatProvider provider, string format, params object[] args)
{
if ((format == null) || (args == null))
{
throw new ArgumentNullException((format == null) ? "format" : "args");
}
StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));
builder.AppendFormat(provider, format, args);
return builder.ToString();
}
Veo AppendFormat
seguido de AppendLine
como no solo más legible, sino también más AppendLine(string.Format(...))
que llamar a AppendLine(string.Format(...))
.
Este último crea una cadena completamente nueva y luego la agrega al por mayor en el constructor existente. No voy a ir tan lejos como para decir "¿Por qué molestarse en usar StringBuilder entonces?" pero parece un poco en contra del espíritu de StringBuilder.
Yo prefiero esta estructura:
sbuilder.AppendFormat("{0} line/n", "First");
Aunque es cierto que hay algo que decir para separar los saltos de línea.
Solo crea un método de extensión.
public static StringBuilder AppendLine(this StringBuilder builder, string format, params object[] args)
{
builder.AppendFormat(format, args).AppendLine();
return builder;
}
Razones por las que prefiero esto:
- No sufre tanta sobrecarga como
AppendLine(string.Format(...))
, como se indicó anteriormente. - Impide que olvide agregar la parte
.AppendLine()
al final (ocurre con la frecuencia suficiente). - Es más legible (pero eso es más una opinión).
Si no te gusta que se llame ''AppendLine'', puedes cambiarlo a ''AppendFormattedLine'' o lo que quieras. Sin embargo, me gusta todo lo relacionado con otras llamadas a ''AppendLine'':
var builder = new StringBuilder();
builder
.AppendLine("This is a test.")
.AppendLine("This is a {0}.", "test");
Simplemente agregue uno de estos para cada sobrecarga que use del método AppendFormat en StringBuilder.