-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Related: https://github.com/dotnet/corefx/issues/30114 (Discussion about introducing a new interface that has TryFormat)
Rationale
TryFormat is as a less-allocating alternative of ToString, which helps us reduce heap allocations by using provided reusable buffers instead of creating a new immutable string every time by calling ToString. However, since it isn't part of any interface/classes, there is no way that people can use it in APIs without hard-coding the type which are known to have TryFormat.
Now that we have Default Interface Methods added to C# 8 (and having it supported in .NET Standard 2.1+ / .NET Core 3.0+), I think it would be great if we can add TryFormat to IFormattable interface as a default interface method, that falls back to the implementation of ToString if not implemented. The allocation caused by fallback if not implemented wouldn't likely be an issue, since there would be no alternatives but to call ToString, which would allocate the same amount of memory. Also, it seems pretty obvious that the behaviour of TryFormat when passed the same format/content should be the same as the one from equivalent ToString call, so calling ToString as a fallback would make sense.
Proposed API
namespace System
{
public interface IFormattable
{
string ToString(string? format, IFormatProvider? formatProvider);
+ bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider);
}
}There is no implementations given in this proposal; However it would be very trivial, calling ToString then attempting to copy the contents of the returned string into the provided Span.
Questions
Would it be worth making format and provider parameters optional for occasions when you just want it to return whatever is the default, given that there isn't a parameter-less TryFormat unlike object.ToString?