Known Limitations
ValueStringBuilder
is a ref struct
. With that comes certain limitations which might make it not a good fit for your needs.
ref struct
s can only live on the stack and therefore cannot be assigned to a field (except for in anotherref struct
s).- Can't be boxed as
object
orValueType
. - Can't be captured by a closure (lambda expression or anonymous function).
- Can't be used in
async
methods. - Can't be used in methods containing
yield
.
If none of these affect your use case, you're good to go. Using ref struct
trades away flexibility in exchange for performance.
ValueStringBuilder
can be converted to a System.Text.StringBuilder
using an extension method in ValueStringBuilderExtensions.
Fluent notation
The built-in StringBuilder
offers a fluent way of appending strings:
var stringBuilder = new StringBuilder();
var greeting = stringBuilder
.AppendLine("Hello")
.AppendLine("World")
.Append("Not a new line afterwards")
.ToString();
This does not work with ValueStringBuilder
. The reason: struct
s can't return ref this
. If we return by-value then the builder is copied and the original will not be updated. Therefore it's a conscious design decision not to allow fluent notation.
IDisposable
ValueStringBuilder
implements IDisposable
(even though it cannot be boxed). The reason is to return any rented arrays to the array pool. As such, the using
keyword should be used with ValueStringBuilder
.
using var stringBuilder = new ValueStringBuilder();
The only scenario where you can avoid disposing the ValueStringBuilder
is when you initialize it with your own buffer and you are sure that the capacity will not increase. It is recommended to dispose it anyway to make sure.
// Reserve 128 bytes on the stack and omit the using keyword
using var stringBuilder = new ValueStringBuilder(stackalloc char[128]);
// Append 11 bytes
stringBuilder.Append("Hello World");
return stringBuilder.ToString();