Когда вы используете StringBuilder.AppendLine/string.Format против StringBuilder.AppendFormat?

Недавно возник вопрос об использовании String.Format(). Часть моего ответа включала предложение использовать StringBuilder.AppendLine(string.Format(...)). Джон Скит предположил, что это плохой пример, и предложил использовать комбинацию AppendLine и AppendFormat.

Мне пришло в голову, что я никогда не выбирал "предпочтительный" подход к использованию этих методов. Я думаю, что я мог бы начать использовать что-то вроде следующего, но мне интересно узнать, что другие люди используют в качестве "лучшей практики":

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"));

7 ответов

Решение

Я смотрю AppendFormat с последующим AppendLine как не только более читаемый, но и более производительный, чем вызывающий AppendLine(string.Format(...)),

Последний создает совершенно новую строку, а затем добавляет ее оптом в существующего застройщика. Я не собираюсь заходить так далеко, чтобы сказать: "Зачем тогда использовать StringBuilder?" но это кажется немного против духа StringBuilder.

Просто создайте метод расширения.

public static StringBuilder AppendLine(this StringBuilder builder, string format, params object[] args)
{
    builder.AppendFormat(format, args).AppendLine();
    return builder;
}

Причины, по которым я предпочитаю это:

  • Не страдает так много накладных расходов, как AppendLine(string.Format(...)), как указано выше.
  • Помешает мне забыть добавить .AppendLine() часть в конце (случается достаточно часто).
  • Это более читабельно (но это больше мнение).

Если вам не нравится, когда он называется "AppendLine", вы можете изменить его на "AppendFormattedLine" или что угодно. Мне нравится все, что совпадает с другими вызовами "AppendLine", хотя:

var builder = new StringBuilder();

builder
    .AppendLine("This is a test.")
    .AppendLine("This is a {0}.", "test");

Просто добавьте один из них для каждой перегрузки, которую вы используете для метода AppendFormat в StringBuilder.

String.format создает объект StringBuilder внутри. При выполнении

sbuilder.AppendLine( String.Format( "{0} line", "First"));

создается дополнительный экземпляр компоновщика строк со всеми его издержками.


Отражатель на 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();
}

Если важна производительность, старайтесь полностью избегать AppendFormat(). Вместо этого используйте несколько вызовов Append() или AppendLine(). Это делает ваш код больше и менее читабельным, но это быстрее, потому что не нужно разбирать строки. Разбор строк происходит медленнее, чем вы можете себе представить.

Я обычно использую:

sbuilder.AppendFormat("{0} line", "First");
sbuilder.AppendLine();
sbuilder.AppendFormat("{0} line", "Second");
sbuilder.AppendLine();

Если производительность не критична, в этом случае я бы использовал:

sbuilder.Append("First");
sbuilder.AppendLine(" line");
sbuilder.Append("Second");
sbuilder.AppendLine(" line");

(Конечно, это будет иметь больше смысла, если "Первый" и "Второй", где не строковые литералы)

AppendFormat() намного удобнее для чтения, чем AppendLine(String.Format())

Это просто ужасно просто использовать

sbuilder.AppendFormat("{0} line\n", first);

? Я имею в виду, я знаю, что он не зависит от платформы или что-то еще, но в 9 из 10 случаев он выполняет свою работу.

Я предпочитаю эту структуру:

sbuilder.AppendFormat("{0} line\n", "First");

Хотя, по общему признанию, есть кое-что, что нужно сказать для выделения разрывов строк.

Другие вопросы по тегам