Подтвердить что ты не робот

Когда вы используете StringBuilder.AppendLine/string.Format vs. 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"));
4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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


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

Ответ 3

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

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.

Ответ 4

Если производительность важна, постарайтесь полностью отказаться от 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");

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

Ответ 5

AppendFormat() намного читаем, чем AppendLine (String.Format())

Ответ 6

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

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

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

Ответ 7

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

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

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