Quando você usa StringBuilder.AppendLine / string.Format vs. StringBuilder.AppendFormat?
-
20-08-2019 - |
Pergunta
Uma pergunta href="https://stackoverflow.com/questions/349659/stringformat-or-not"> recente sobre usando String.Format (). Parte da minha resposta incluiu uma sugestão para usar StringBuilder.AppendLine (string.Format (...)). Jon Skeet sugeriu este era um mau exemplo e propôs usando uma combinação de AppendLine e AppendFormat.
Ocorreu-me que eu nunca realmente me acomodou-se numa abordagem "preferido" para o uso desses métodos. Eu acho que eu poderia começar a usar algo como o seguinte, mas estou interessado em saber o que as outras pessoas usam como uma "melhor prática":
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"));
Solução
I ver AppendFormat
seguido por AppendLine
não apenas como mais legível, mas também mais eficaz do que chamar AppendLine(string.Format(...))
.
Este último cria uma cadeia totalmente novo e, em seguida, anexa atacado para o construtor existente. Eu não estou indo para ir tão longe como dizer "Por que se preocupar usando StringBuilder, então?" mas parece um pouco contra o espírito do StringBuilder.
Outras dicas
Basta criar um método de extensão.
public static StringBuilder AppendLine(this StringBuilder builder, string format, params object[] args)
{
builder.AppendFormat(format, args).AppendLine();
return builder;
}
As razões que eu prefiro este:
- Não sofre tanto sobrecarga como
AppendLine(string.Format(...))
, como indicado acima. - Impede-me de esquecer de adicionar a parte
.AppendLine()
no final (acontece com freqüência suficiente). - É mais legível (mas isso é mais uma opinião).
Se você não gosta de ser chamado 'AppendLine,' você poderia mudá-lo para 'AppendFormattedLine' ou o que quiser. I desfrutar de tudo, alinhando com outras chamadas para 'AppendLine' embora:
var builder = new StringBuilder();
builder
.AppendLine("This is a test.")
.AppendLine("This is a {0}.", "test");
Basta adicionar um destes para cada sobrecarga você usa do método AppendFormat em StringBuilder.
String.format cria um objeto StringBuilder internamente. Ao fazer
sbuilder.AppendLine( String.Format( "{0} line", "First"));
uma instância adicional do construtor corda, com toda a sua sobrecarga é criado.
refletor em 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 o desempenho é importante, para tentar evitar AppendFormat () completamente. Uso múltiplo Anexar () ou AppendLine () chama em seu lugar. Isto faz seu código maior e menos legível, mas é mais rápido porque há análise de cadeia tem de ser feito. Cordas de análise é mais lento do que você pode imaginar.
Eu geralmente uso:
sbuilder.AppendFormat("{0} line", "First");
sbuilder.AppendLine();
sbuilder.AppendFormat("{0} line", "Second");
sbuilder.AppendLine();
A menos que o desempenho é crítico, caso em que eu usaria:
sbuilder.Append("First");
sbuilder.AppendLine(" line");
sbuilder.Append("Second");
sbuilder.AppendLine(" line");
(Claro, isso faria mais sentido se "First" e "Segundo", onde não strings literais)
AppendFormat () é muito mais legível do que AppendLine (String.Format ())
Eu prefiro esta estrutura:
sbuilder.AppendFormat("{0} line\n", "First");
Embora reconhecidamente há algo a ser dito para separar as quebras de linha.
É apenas positivamente terrível de usar simplesmente
sbuilder.AppendFormat("{0} line\n", first);
? Quer dizer, eu sei que não é independente de plataforma ou o que quer, mas em 9 de cada 10 casos, começa o trabalho feito.