Vogen icon indicating copy to clipboard operation
Vogen copied to clipboard

IFormatProvider enhancements

Open Allann opened this issue 9 months ago • 1 comments

Describe the feature

I have multiple temperature types and each has a suffix I'd like to apply via a format provider. Since there isn’t a mechanism to “register” a default format provider for a type globally I'd like the opportunity to provide one. For example:

Image

There are numerous other places I'd like to insert the format provider too if the passed one is null.

More examples in my manually created type:

public sealed class Celcius : IFormattable
{
    // Your custom default format provider, for instance as a singleton.
    public static readonly IFormatProvider DefaultFormatProvider = new CelsiusFormatProvider();

    // IFormattable implementation
    public string ToString(string format, IFormatProvider formatProvider)
    {
        // Use default format provider if none is provided.
        formatProvider ??= DefaultFormatProvider;

        // If format is null or empty, default to "G"
        if (string.IsNullOrEmpty(format))
            format = "G";

sample of the default format provider:


/// <summary>
/// Provides formatting for Celsius values, appending the "°C" symbol.
/// </summary>
public class CelsiusFormatProvider : IFormatProvider, ICustomFormatter
{
    private readonly IFormatProvider _parentProvider;
    private const string CelsiusSymbol = "°C";

    public CelsiusFormatProvider() : this(CultureInfo.CurrentCulture)
    {
    }

    public CelsiusFormatProvider(IFormatProvider parentProvider)
    {
        _parentProvider = parentProvider;
    }

    /// <summary>
    /// Returns an object that provides formatting services for the specified type.
    /// </summary>
    public object? GetFormat(Type? formatType)
    {
        return formatType == typeof(ICustomFormatter) ? this : (object?)null;
    }

    /// <summary>
    /// Converts the value of a specified object to an equivalent string representation
    /// using specified format and culture-specific formatting information.
    /// </summary>
    public string Format(string? format, object? arg, IFormatProvider? formatProvider)
    {
        // Return null to let other formatters handle this if not a Celsius value
        if (arg is null or not Celcius)
        {
            return HandleOtherFormats(format, arg);
        }

        Celcius celsius = (Celcius)arg;
        if (!celsius.IsInitialized())
        {
            return "[UNINITIALIZED]";
        }

        string formattedNumber;

        // Handle "C" format specifically for Celsius 
        if (string.Equals(format, "C", StringComparison.OrdinalIgnoreCase))
        {
            formattedNumber = celsius.Value.ToString("0.##", _parentProvider);
            return $"{formattedNumber}{CelsiusSymbol}";
        }

        // Use specified format (or default if null) for the number portion
        formattedNumber = celsius.Value.ToString(format, _parentProvider);
        return $"{formattedNumber}{CelsiusSymbol}";
    }

    private string HandleOtherFormats(string? format, object? arg)
    {
        return arg is IFormattable formattable ? formattable.ToString(format, _parentProvider) : arg?.ToString() ?? string.Empty;
    }

    /// <summary>
    /// Attempts to parse a string that might contain the Celsius symbol.
    /// </summary>
    /// <param name="s">The string to parse.</param>
    /// <param name="result">The decimal result if parsing succeeds.</param>
    /// <returns>True if parsing succeeds, false otherwise.</returns>
    public static bool TryParseCelsiusString(string? s, out decimal result)
    {
        result = 0;

        if (string.IsNullOrWhiteSpace(s))
        {
            return false;
        }

        // Remove the Celsius symbol if present
        string valueToParse = s.Replace(CelsiusSymbol, "").Trim();

        return decimal.TryParse(valueToParse, out result);
    }
}

Allann avatar Mar 27 '25 03:03 Allann

Thanks for the feedback! Apologies for the very slow response. I'll hopefully get around to addressing a few issues soon.

SteveDunn avatar Nov 26 '25 22:11 SteveDunn