When do you use StringBuilder.AppendLine/string.Format vs. StringBuilder.AppendFormat?

28,813

Solution 1

I view AppendFormat followed by AppendLine as not only more readable, but also more performant than calling AppendLine(string.Format(...)).

The latter creates a whole new string and then appends it wholesale into the existing builder. I'm not going to go as far as saying "Why bother using StringBuilder then?" but it does seem a bit against the spirit of StringBuilder.

Solution 2

Just create an extension method.

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

Reasons I prefer this:

  • Doesn't suffer as much overhead as AppendLine(string.Format(...)), as stated above.
  • Prevents me from forgetting to add the .AppendLine() part at the end (happens frequently enough).
  • Is more readable (but that is more of an opinion).

If you don't like it being called 'AppendLine,' you could change it to 'AppendFormattedLine' or whatever you want. I enjoy everything lining up with other calls to 'AppendLine' though:

var builder = new StringBuilder();

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

Just add one of these for each overload you use of the AppendFormat method on StringBuilder.

Solution 3

String.format creates a StringBuilder object internally. By doing

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

an additional instance of string builder, with all of its overhead is created.


Reflector on 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();
}

Solution 4

If performance is important, try to avoid AppendFormat() completely. Use multiple Append() or AppendLine() calls instead. This does make your code larger and less readable, but it's faster because no string parsing has to be done. String parsing is slower than you might imagine.

I generally use:

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

Unless performance is critical, in which case I'd use:

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

(Of course, this would make more sense if "First" and "Second" where not string literals)

Share:
28,813
Neil Barnwell
Author by

Neil Barnwell

I'm an Application Developer and Software Architect for a wide variety of software solutions including websites and desktop applications. Most recently focussed on a bespoke warehouse management system using C# 3.5 and SQL Server 2008. Since my move to .NET I've become active in the community, attending monthly usergroup meetings and various conferences. I've even made a foray into speaking at usergroups about topics I am passionate about. While I love experimenting with new tech and have a hobby project hosted on CodePlex, my current focus is less on specific new technologies and more on good principles and techniques. When not at work I'm a family man, biker, amateur photographer, guitarist and of course, software developer.

Updated on July 31, 2020

Comments

  • Neil Barnwell
    Neil Barnwell almost 4 years

    A recent question came up about using String.Format(). Part of my answer included a suggestion to use StringBuilder.AppendLine(string.Format(...)). Jon Skeet suggested this was a bad example and proposed using a combination of AppendLine and AppendFormat.

    It occurred to me I've never really settled myself into a "preferred" approach for using these methods. I think I might start using something like the following but am interested to know what other people use as a "best practice":

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