The StringBuilder Class

Solve issues related to immutability using StringBuilder.

Introduction

The System.String namespace offers a plethora of methods for handling text. We could even create our own text editor. Remember, though, that a new string is created any time we make a change to a string object. That’s the nature of strings, they are immutable. This can be a problem if our program handles large texts and makes many changes. Memory allocation is a costly operation in terms of memory and processing power.

There must be something dynamic and mutable, something that can be modified in-place instead of created from scratch. Fortunately, .NET provides the StringBuilder class, which is like a mutable version of System.String.

Using StringBuilder

Note: The StringBuilder class is located in the System.Text namespace.

Mutability is achieved through the allocation more space than is required:

C#
using System;
using System.Text;
namespace UsingStringBuilder
{
class Program
{
static void Main(string[] args)
{
var stringBuilder = new StringBuilder("Hello World!");
Console.WriteLine($"Length of the string stored inside: {stringBuilder.Length}.");
Console.WriteLine($"Current total capacity: {stringBuilder.Capacity}.");
}
}
}

Here, "Hello World!" is 12 characters long, but StringBuilder allocates space for 16 characters by default. This capacity is doubled whenever the length of the string reaches the current capacity:

C#
using System;
using System.Text;
namespace UsingStringBuilder
{
class Program
{
static void Main(string[] args)
{
var stringBuilder = new StringBuilder("Hello World!");
Console.WriteLine($"Length of the string stored inside: {stringBuilder.Length}.");
Console.WriteLine($"Current total capacity: {stringBuilder.Capacity}.");
Console.WriteLine("Appending to the StringBuilder object...");
stringBuilder.Append(" Hello once again!");
Console.WriteLine($"New length: {stringBuilder.Length}.");
Console.WriteLine($"New total capacity: {stringBuilder.Capacity}.");
}
}
}

After appending to the StringBuilder object, the new length is 30 characters. Because this length is less than 32 (16 x 2), the capacity only doubled. If the length were more than double the current capacity, the new capacity would equal the new length:

C#
using System;
using System.Text;
namespace UsingStringBuilder
{
class Program
{
static void Main(string[] args)
{
var stringBuilder = new StringBuilder("Hello World!");
Console.WriteLine($"Length of the string stored inside: {stringBuilder.Length}.");
Console.WriteLine($"Current total capacity: {stringBuilder.Capacity}.");
Console.WriteLine("Appending to the StringBuilder object...");
stringBuilder.Append(" Hello once again!!!!!");
Console.WriteLine($"New length: {stringBuilder.Length}.");
Console.WriteLine($"New total capacity: {stringBuilder.Capacity}.");
}
}
}

Notice that the capacity and the length are now both 34.

So, memory allocation does happen, but not each time the contents of the StringBuilder object change. Memory is only allocated when the current capacity is full.

Note: f we know that we’ll append to the StringBuilder object many times, we can estimate how much memory we need and provide this number to the constructor. This way, we avoid constant memory allocation.

The StringBuilder methods

The StringBuilder class does not enjoy the same variety of methods as System.String. However, the class does provide enough functionality to effectively work with textual information:

  • The Insert() method inserts a given substring to a certain position.
  • The Append() method appends a substring to the end of the StringBuilder object. The AppendLine() method does the same thing but also inserts a line break at the end (similar to Console.Write() and Console.WriteLine()).
  • The Replace() method replaces all occurrences of a given character or substring with another character or substring.
  • The Remove() method removes a certain number of characters, starting with a given index (just like in System.String).

Note: Remember that a StringBuilder object isn’t an instance or child of System.String. Use the ToString() method to get the string stored inside.