Editing the content
editInsert, replace, truncate and clear
// Not a using declaration: it would make the variable read-only, and Length could not be set
var sb = new ValueStringBuilder(stackalloc char[64]);
sb.Append("Hello World");
sb.Insert(5, ",");
sb.Insert(0, ">> ");
sb[3] = 'h'; // the indexer returns a reference: assign to replace a character
Assert.Equal(">> hello, World", sb.AsSpan());
sb.Length = 9; // setting Length truncates the content
Assert.Equal(">> hello,", sb.AsSpan());
sb.Clear(); // Length is 0 again; the buffer is kept
sb.Append("Done");
// ToString returns the content and disposes the builder
Assert.Equal("Done", sb.ToString());Insert(index, string?)inserts a string, andInsert(index, char, count)a character repeatedcounttimes. The index must be between 0 and Length.- The indexer returns a reference to a character of the content: read it, or assign it to replace the character. The index must be less than Length.
- Setting Length to a smaller value truncates the content. Setting it to a larger value exposes the characters already present in the buffer, which may be anything: see Pitfalls.
- Clear sets Length to 0 and keeps the buffer, so the builder can be reused without growing again.
The builder in this example is not declared with using: a using declaration makes the variable read-only, so Length could not be set. See Pitfalls.
Write directly into the buffer
AppendSpan(length) reserves length characters at the end of the content and returns them as a Span<char>, for APIs that write into a span, such as TryFormat or Convert.TryToBase64Chars:
using var sb = new ValueStringBuilder(stackalloc char[64]);
sb.Append("id=");
// Reserve 8 characters at the end of the content and write them directly
var destination = sb.AppendSpan(8);
Assert.True(0xCAFE.TryFormat(destination, out var written, "X8", CultureInfo.InvariantCulture));
Assert.Equal(8, written);
Assert.Equal("id=0000CAFE", sb.AsSpan());Length is advanced immediately: the reserved characters are part of the content whether you write them or not. Reserve exactly the number of characters you write, or reduce Length afterwards.
Capacity
// Without an initial buffer, the builder rents one of at least 256 characters from ArrayPool<char>.Shared
using var sb = new ValueStringBuilder(initialCapacity: 256);
Assert.True(sb.Capacity >= 256);
// Grow once before a series of appends whose total length you know
sb.EnsureCapacity(1024);
Assert.True(sb.Capacity >= 1024);- Capacity is the number of characters the current buffer holds before it has to grow.
EnsureCapacity(capacity)grows the buffer once to hold at leastcapacitycharacters. Call it before a series of appends whose total length you know, rather than letting the buffer grow several times.- Growing rents a larger array from the pool, copies the content into it, and returns the previous rented array.
Use the builder with native code
NullTerminate writes a null character after the content, growing the buffer if needed, without changing Length. GetPinnableReference returns a reference to the first character, so the builder can be used in a fixed statement to pass the content to native code. The content is only null-terminated after a call to NullTerminate.