BlackWasp
.NET Framework
.NET 1.1+

The StringBuilder Class

Creating strings with the use of multiple concatenation operations can lead to low performance and wasteful memory usage. The StringBuilder class allows strings to be created and updated without the problems caused by the immutability of the String class.

What is a StringBuilder?

Objects of the String class are immutable. That is, once created in memory, a string instance cannot be modified. In order for a string to appear changeable, every modification to its contents causes a new object to be generated, using addition memory and, potentially, lowering the performance of an application.

The StringBuilder class provides string-like functionality by storing a mutable series of characters. These individual characters can be read and modified via an indexer. The contents can also be changed using concatenation, insertion and deletion methods. Once any building process is complete, the contents can be extracted to a string for further use.

One of the primary uses of StringBuilder is for multiple concatenation operations, especially when the modifications occur within a large loop. StringBuilders generally give better performance and a lower memory footprint when working with large strings or when the number of concatenations is variable. For low and fixed numbers of concatenations, particularly when not within a loop, simple strings can give better performance.

Using StringBuilders

In this article we will demonstrate the key methods and properties of the StringBuilder class with simple examples. To follow the examples create a new console application project. As the StringBuilder class is found in the System.Text namespace, ensure that the following using directive is present in the class file. All of the examples that follow can be tested using the Main method of the project.

using System.Text;

Creating a StringBuilder

The StringBuilder class includes six constructors, including a default constructor that requires no arguments. The default constructor creates a new StringBuilder object that contains an empty string. We can see this by using the ToString method, which returns the StringBuilder's contents as a string.

StringBuilder sb = new StringBuilder();
Console.WriteLine(sb.ToString() == string.Empty);   // Outputs "True"

When a StringBuilder object is instantiated, a capacity for the contents is determined and memory is allocated. When using the basic constructor, the capacity is set to a default value. If the size of the string within the StringBuilder exceeds this capacity, the available size is increased automatically. This can lead to the allocated of more memory than is required. To minimise this possibility, you can elect to specify the initial capacity of a StringBuilder with a single integer parameter. If the parameter is zero, the default capacity is used.

The following sample initialises the capacity to fifty characters:

StringBuilder sb = new StringBuilder(50);

It is possible to specify a maximum capacity for a StringBuilder object. The default maximum size is 2,147,483,647 characters. If the maximum capacity is exceeded, an exception is thrown. To specify the capacity and maximum capacity you can use a constructor that accepts two integer parameters.

The following creates a StringBuilder with an initial capacity of fifty characters and a maximum size of two hundred characters:

StringBuilder sb = new StringBuilder(50, 200);

Each of the three constructors described above initialises a StringBuilder with an empty string. The remaining three constructors can be used when you wish to set the contents during instantiation. The simplest accepts a string as its only argument. The string is used as the initial content of the new object. The default capacity is used for the StringBuilder, though this may be immediately increased if the capacity is insufficient for the supplied contents. If the initial string is null, the StringBuilder will contain an empty string.

StringBuilder sb = new StringBuilder("BlackWasp");
Console.WriteLine(sb);                              // Outputs "BlackWasp"

sb = new StringBuilder();
Console.WriteLine(sb.ToString() == string.Empty);   // Outputs "True"

To set the contents and the initial capacity, specify the capacity as the second argument:

StringBuilder sb = new StringBuilder("BlackWasp", 50);

The final constructor initialises the contents of the new StringBuilder using a substring of an existing string. The first parameter is the string from which to extract some text. The second and third parameters define the starting point and the number of characters to use. A fourth parameter specifies the starting capacity of the object.

string aString = "The quick brown fox.";
StringBuilder sb = new StringBuilder(aString, 4, 5, 50);
Console.WriteLine(sb);  // Outputs "quick"

StringBuilder Properties

Capacity

The Capacity property can be read to obtain the current character capacity of the StringBuilder. You can also set this property to increase or decrease the capacity and associated memory allocation. You may not reduce the capacity to a value lower than the overall length of the object's contents.

StringBuilder sb = new StringBuilder("Hello, world!");
Console.WriteLine(sb.Capacity);
sb.Capacity = 13;
Console.WriteLine(sb.Capacity);

/* OUTPUT

16
13

*/

MaxCapacity

The maximum capacity for a StringBuilder may only be set using a constructor. You can, however, obtain the maximum capacity by reading the MaxCapacity property.

StringBuilder sb = new StringBuilder("Hello, world!");
Console.WriteLine(sb.MaxCapacity);  // Outputs "2147483647"

Length

The Length property can be read to obtain the current length of a StringBuilder's contents. You may also set this property to change the length. Reducing the length causes the contents to be truncated. Increasing the length pads the end of the StringBuilder with null characters.

StringBuilder sb = new StringBuilder("Hello, world!");
sb.Length = 5;
Console.WriteLine(sb);  // Outputs "Hello"

Chars

The Chars property provides direct access to each of the characters held within the StringBuilder. This property is an indexer so when accessed using C#, the property name is not used. As with standard strings, the indexer can be used to read any single character. Unlike with the String class, you can also change the value of individual characters by assigning a value.

StringBuilder sb = new StringBuilder("Hello, world!");
sb[12] = '?';
Console.WriteLine(sb);  // Outputs "Hello, world?"

Modifying StringBuilder Contents

The key benefits of the StringBuilder class are seen when modifying the contained string. In this section we will examine six methods that allow characters to be appended, inserted, modified and deleted.

Append

The Append method can be used to add characters to the end of the contents of a StringBuilder. In many cases a string will be appended. However, the Append method includes many overloaded versions, each appending a string representation of a value or object.

string player = "Bob";
int points = 1234;
TimeSpan duration = new TimeSpan(1, 30, 0);

StringBuilder sb = new StringBuilder();
sb.Append(player);
sb.Append(" scored ");
sb.Append(points);
sb.Append(" points in ");
sb.Append(duration);
sb.Append(".");

Console.WriteLine(sb);  // Outputs "Bob scored 1234 points in 01:30:00."

NB: The above code is for example purposes only. Such simple concatenation could be achieved more efficiently using string concatenation or the String.Format method.

AppendFormat

The AppendFormat method allows a composite format string to be added to the end of the existing contents. A composite format string contains placeholder symbols in braces that are replaced with the contents of additional parameters. For more information about composite format strings, see the article, "C# String Generation with String.Format".

string player = "Bob";
int points = 1234;
TimeSpan duration = new TimeSpan(1, 30, 0);

StringBuilder sb = new StringBuilder();
sb.AppendFormat("The winner was {0}.", player);
sb.Append("\n");
sb.AppendFormat("This player scored {0:#,#} points in {1}.", points, duration);

Console.WriteLine(sb);

/* OUTPUT

The winner was Bob.
This player scored 1,234 goals in 01:30:00.

*/

NB: The AppendFormat method may generate additional strings during the process of concatenation. Sometimes greater performance and lower memory usage will be achieved by using several Append methods, rather than a single call to AppendFormat.

AppendLine

The AppendLine method can be used in two ways. If no parameter is provided, the method simply adds a standard line break to the end of the StringBuilder's contents. If a string parameter is specified, the text is appended to the StringBuilder before the new line break.

string player = "Bob";
int points = 1234;
TimeSpan duration = new TimeSpan(1, 30, 0);

StringBuilder sb = new StringBuilder();
sb.Append("The winner was ");
sb.Append(player);
sb.AppendLine(".");
sb.AppendFormat("This player scored {0:#,#} points in {1}.", points, duration);

Console.WriteLine(sb);

/* OUTPUT

The winner was Bob.
This player scored 1,234 goals in 01:30:00.

*/

Insert

In addition to concatenating strings, the StringBuilder class allows a string to be inserted at any position within its contents, using the Insert method. This method accepts two arguments. The first specified the position at which characters should be inserted. The second parameter can be any value or object. The string representation of the second parameter is added at the desired location.

StringBuilder sb = new StringBuilder();
sb.Append("The winner was .");
sb.Insert(15, "Bob");
Console.WriteLine(sb);  // Outputs "The winner was Bob."

Replace

The Replace method allows a simple "search and replace" operation to be carried out upon the contents of a StringBuilder. You can search for a single character or an entire string to be replaced with an alternative. The following sample uses strings.

StringBuilder sb = new StringBuilder();
sb.Append("The winner was Bob.");
sb.Replace("Bob", "Jan");
Console.WriteLine(sb);  // Outputs "The winner was Jan."

NB: The Replace method can also be used to replace characters within a substring of the StringBuilder's contents by providing a starting index and length for the substring.

Remove

The last member for changing a StringBuilder's contents is the Remove method. This method removes a substring that is defined using a start index and length.

StringBuilder sb = new StringBuilder();
sb.Append("The winner was NOT Bob.");
sb.Remove(14, 4);
Console.WriteLine(sb);  // Outputs "The winner was Bob."

Chaining Methods

One interesting aspect of the six methods described above is that each returns a reference to the StringBuilder. This provides the possibility of chaining the methods together, which can lead to code that is easier to read and maintain. When chaining methods together, they are executed in the order in which they appear. For example:

string player = "Bob";
int points = 1234;
TimeSpan duration = new TimeSpan(1, 30, 0);

StringBuilder sb = new StringBuilder();
sb.Append("The winner was ")
  .Append(player)
  .AppendLine(".")
  .AppendFormat("This player scored {0:#,#} points in {1}.", points, duration)
  .Replace("Bob", "Jan");

Console.WriteLine(sb);

/* OUTPUT

The winner was Jan.
This player scored 1,234 goals in 01:30:00.

*/
Link to this Page25 October 2009
TwitterTwitter RSS Feed RSS