I have a string input. I want to remove the last symbol from it. I can do it in this way:
static void Main(string[] args)
{
    string input = "Hello World-";
    string result = input.TrimEnd('-');
    Console.WriteLine(result); // Hello World
}
It works, but TrimEnd() calls System.String.FastAllocateString() internally. It makes sense, because string is immutable data structure, and in common case we cannot do anything else. However, in my case I don't need input anymore, so I would like to reuse its internal buffer, rather than allocate additional buffer, and "ask" GC to clean input buffer eventually. It could reduce overall allocations, and reduce GC work.
Console.Out.WriteLine does not accept a ReadOnlySpan<char> as input, but Console.Out, which is a TextWriter, does expose such a method. Therefore, the correct way to avoid allocations is:
ReadOnlySpan<char> input = "Hello World-";
Console.Out.WriteLine(input.TrimEnd('-'));
// or
// Uses an indexer to always remove the last character:
Console.Out.WriteLine(input[..^1]);
If you need a string as result and you have to apply several string operations on the input, then using a ReadOnlySpan<char> will save you repeated allocations on the intermediate results, but in the end you will have to allocate a new string and the possible string operations are very limited. Unless you are willing to use unsafe code or to make a detour via COM code, there is no way to break this rule.
Alternatively, you can use a StringBuilder for string manipulations. But this will allocate a char[] buffer and ToString calls FastAllocateString as well. See Reference Source for StringBuilder.
This is what the ReadOnlySpan struct & System.Memory namespace are for
ReadOnlySpan<char> input = "Hello World-";
string result = new string(input.TrimEnd('-'));
Console.WriteLine(result);
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With