Quando usi StringBuilder.AppendLine / string.Format vs. StringBuilder.AppendFormat?
-
20-08-2019 - |
Domanda
È stata posta una recente sull'utilizzo di String.Format (). Parte della mia risposta includeva un suggerimento per usare StringBuilder.AppendLine (string.Format (...)). Jon Skeet ha suggerito che questo è stato un cattivo esempio e ha proposto di utilizzare una combinazione di AppendLine e AppendFormat.
Mi è venuto in mente che non mi sono mai veramente inserito in un " preferito " approccio per l'utilizzo di questi metodi. Penso che potrei iniziare a usare qualcosa di simile al seguente ma sono interessato a sapere cosa usano gli altri come & Quot; best practice & Quot ;:
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"));
Soluzione
Visualizzo AppendFormat
seguito da AppendLine
non solo come più leggibile, ma anche più performante rispetto alla chiamata AppendLine(string.Format(...))
.
Quest'ultimo crea una stringa completamente nuova e quindi la aggiunge all'ingrosso al builder esistente. Non ho intenzione di dire & Quot; Perché preoccuparsi di usare StringBuilder allora? & Quot; ma sembra un po 'contrario allo spirito di StringBuilder.
Altri suggerimenti
Basta creare un metodo di estensione.
public static StringBuilder AppendLine(this StringBuilder builder, string format, params object[] args)
{
builder.AppendFormat(format, args).AppendLine();
return builder;
}
Ragioni per cui preferisco questo:
- Non soffre tanto di sovraccarico quanto
AppendLine(string.Format(...))
, come indicato sopra. - Mi impedisce di dimenticare di aggiungere la
.AppendLine()
parte alla fine (succede abbastanza frequentemente). - È più leggibile (ma è più un'opinione).
Se non ti piace che venga chiamato 'AppendLine', puoi cambiarlo in 'AppendFormattedLine' o come vuoi. Mi piace tutto in fila con altre chiamate a "AppendLine":
var builder = new StringBuilder();
builder
.AppendLine("This is a test.")
.AppendLine("This is a {0}.", "test");
Basta aggiungere uno di questi per ogni sovraccarico che usi del metodo AppendFormat su StringBuilder.
String.format crea internamente un oggetto StringBuilder. Facendo
sbuilder.AppendLine( String.Format( "{0} line", "First"));
viene creata un'istanza aggiuntiva di string builder, con tutto il suo overhead.
Riflettore su 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();
}
Se le prestazioni sono importanti, cerca di evitare completamente AppendFormat (). Utilizzare invece più chiamate Append () o AppendLine (). Questo rende il codice più grande e meno leggibile, ma è più veloce perché non è necessario eseguire l'analisi delle stringhe. L'analisi delle stringhe è più lenta di quanto si possa immaginare.
In genere utilizzo:
sbuilder.AppendFormat("{0} line", "First");
sbuilder.AppendLine();
sbuilder.AppendFormat("{0} line", "Second");
sbuilder.AppendLine();
A meno che le prestazioni non siano critiche, nel qual caso userei:
sbuilder.Append("First");
sbuilder.AppendLine(" line");
sbuilder.Append("Second");
sbuilder.AppendLine(" line");
(Naturalmente, questo avrebbe più senso se " Primo " e " Secondo " dove non i letterali stringa)
AppendFormat () è molto più leggibile di AppendLine (String.Format ())
Preferisco questa struttura:
sbuilder.AppendFormat("{0} line\n", "First");
Anche se è vero che c'è qualcosa da dire per separare le interruzioni di linea.
È semplicemente terribile semplicemente usare
sbuilder.AppendFormat("{0} line\n", first);
? Voglio dire, so che non è indipendente dalla piattaforma o altro, ma in 9 casi su 10 ottiene il lavoro svolto.