Repository navigation
Description
Background and motivation
There are many methods for working with the contents by using the ReadOnlySequence<char> structure:
- https://learn.microsoft.com/en-us/dotnet/standard/io/buffers
- https://learn.microsoft.com/en-us/dotnet/standard/io/pipelines
There are no such methods for the StringBuilder class, and it is often used as a buffer to create string content quickly and conveniently. Therefore, there is a desire to work with the contents of the StringBuilder class as quickly and conveniently as with the contents of the ReadOnlySequence<char> structure.
There are 3 ways to deal with the contents of a StringBuilder as ways as with the ReadOnlySequence<char> structure:
-
Create a string and use it. This is not optimal.
-
Use the
StringBuilder.GetChunks()method and implement the required methods yourself, repeating the methods already written for theReadOnlySequence<char>structure. This is probably the fastest in terms of code performance, but very costly to implement and test. -
Convert the
StringBuilder.ChunkEnumeratorstructure to aReadOnlySequence<char>structure and use it further in the already written methods for working with buffers and memory. Implementing such a conversion in third-party libraries will not be the most efficient without access to the internal fields of theStringBuilderclass. This conversion can be done more efficiently by accessing the internal fields of theStringBuilderclass.
I propose to add to the StringBuilder class (as an option in the extension methods) methods to get its contents as a ReadOnlySequence<char> structure.
API Proposal
namespace System.Text;
public class StringBuilder
{
public ChunkReverseEnumerator GetReverseChunks(); // will allow us to create performance and memory-efficient code
}
// Assembly: System.Memory.dll
namespace System.Buffers;
public static class BuffersExtensions
{
public static ReadOnlySequence<char> AsSequence(this StringBuilder builder); // OR GetSequence(); OR ToSequence();
public static ReadOnlySequence<char> AsSequence(this StringBuilder builder, int startIndex, int length);
}API Usage
Wherever the ReadOnlySequence<T> class is used:
- https://learn.microsoft.com/en-us/dotnet/standard/io/buffers
- https://learn.microsoft.com/en-us/dotnet/standard/io/pipelines
- https://learn.microsoft.com/en-us/dotnet/api/system.text.encodingextensions
- https://learn.microsoft.com/en-us/dotnet/api/system.buffers.buffersextensions
- https://learn.microsoft.com/en-us/dotnet/api/system.buffers.sequencereader-1
- https://learn.microsoft.com/en-us/dotnet/api/system.io.pipelines.pipereader.create
- https://learn.microsoft.com/en-us/dotnet/api/system.io.pipelines.readresult.-ctor
- https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsondocument.parse
- https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.sequencemarshal
Alternative Designs
Repeating the methods already written for the ReadOnlySequence<char> structure for the StringBuilder class.
Risks
The contents of the ReadOnlySequence<char> structure can be changed by changing the contents of the original StringBuilder instance.
Activity
huoyaoyuan commentedon Jun 10, 2023
If we do this on
StringBuilderitself, it would require foldingReadOnlySequenceinto CoreLib.Is this achievable with public api surface of
StringBuilder, usingGetChunks?AlexRadch commentedon Jun 10, 2023
Is
System.Memory.dllnot included in CoreLib?GetChunkscan be used, but such code will be less performance and consume more memory than code that has access to theStringBuilderprivate fields.huoyaoyuan commentedon Jun 10, 2023
CoreLib is referenced by everything, and can't reference anything else. It is a single assembly file and doesn't "include" anything. Don't confuse with shared framework.
AlexRadch commentedon Jun 10, 2023
If add a new
GetChunksmethod that will return chunks in reverse order, then such code can be created in any place and it will be performance and memory effective.AlexRadch commentedon Jun 10, 2023
I rewrote [API Proposal] based on your comments. Thank you!
tannergooding commentedon May 1, 2026
Going to close this as a duplicate. We're unlikely to expose
GetReverseChunksas we don't really expose reverse enumerators in general for any collection type. Then the other functionality is covered by #97570