Когда вы используете 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"));

person Neil Barnwell    schedule 08.12.2008    source источник
comment
возможно, ваш пример кода может проиллюстрировать оба случая? :)   -  person annakata    schedule 08.12.2008


Ответы (7)


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

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

person Jon Skeet    schedule 08.12.2008
comment
Да, я полностью возьмусь за это (и, во-первых, спасибо, что взяли меня за это, BTW). - person Neil Barnwell; 08.12.2008
comment
Нет проблем - и извините, если мой тон в исходном комментарии показался грубым. Иногда со мной так поступает многозадачность :( - person Jon Skeet; 08.12.2008

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

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.

person docmanhattan    schedule 10.09.2013

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();
}
person AdamSane    schedule 08.12.2008

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

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

person Chris    schedule 08.12.2008
comment
Тест, который я сделал, показал 5-кратное увеличение производительности при использовании отдельных вызовов Append () вместо одного вызова AppendFormat () с 4 аргументами. - person Chris; 09.12.2008

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

person Brian Genisio    schedule 08.12.2008

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

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

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

person Joel Coehoorn    schedule 08.12.2008
comment
Я обычно использовал \ r \ n, но предпочитаю Environment.NewLine, который неудобно использовать. Отсюда возникает вопрос. - person Neil Barnwell; 09.12.2008

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

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

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

person Coderer    schedule 08.12.2008