Showing posts with label Parsing Extensions. Show all posts
Showing posts with label Parsing Extensions. Show all posts

August 23, 2026

Parsing Extensions

An idea from Nick Chapsis as shown here https://www.youtube.com/watch?v=lqbYURwM0bw, althought I added the TryParse with default value. These extensions that allow you to call the Parse function on a string or span. This will work with all the Basic types because they will have the static ISpanParsable interface defined for them.

public static class ParsableExtensions
{
	// SPAN Parsing
	
    /// <summary>
    /// Parse a span of characters for a given type <typeparamref name="T"/>
    /// </summary>
    /// <typeparam name="T">Type that supports an ISpanParsable<typeparamref name="T"/> interface</typeparam>
    /// <param name="input">span of characters to parse</param>
    /// <param name="fp">format provider</param>
    /// <returns>The parsed value, will throw an exception if the parsing faile</returns>
    public static T Parse<T>(this ReadOnlySpan<char> input, IFormatProvider? fp = null)
      where T : ISpanParsable<T>
    {
        return T.Parse(input, fp);
    }

    /// <summary>
    /// Parse a span of characters for a given type <typeparamref name="T"/>, the parsed value is returned as an out parameter
    /// </summary>
    /// <typeparam name="T">Type that supports an ISpanParsable<typeparamref name="T"/> interface</typeparam>
    /// <param name="input">span of characters to parse</param>
    /// <param name="fp">format provider</param>
    /// <returns>whether the parse succeeded or not</returns>
    public static bool TryParse<T>(this ReadOnlySpan<char> input, IFormatProvider fp, out T? value)
      where T : ISpanParsable<T>
    {
        return T.TryParse(input, fp, out value);
    }

    /// <summary>
    /// Parse a span of characters for a given type <typeparamref name="T"/>
    /// </summary>
    /// <typeparam name="T">Type that supports an ISpanParsable<typeparamref name="T"/> interface</typeparam>
    /// <param name="input">span of characters to parse</param>
    /// <param name="defaultValue">The value to return if the parsing failed</param>
    /// <returns>The parsed value if the span was successfully parsed, the default value otherwise</returns>
    public static T Parse<T>(this ReadOnlySpan<char> input, T defaultValue)
      where T : ISpanParsable<T>
    {
        T result = T.TryParse(input, null, out T? value) ? value : defaultValue;
        return result;
    }

	/////////////////////////////////////////////////////////////////////////////////
	// STRING parsing

	/// <summary>
	/// Parse a string for a given type <typeparamref name="T"/>
	/// </summary>
	/// <typeparam name="T">Type that supports an ISpanParsable<typeparamref name="T"/> interface</typeparam>
	/// <param name="input">string to parse</param>
	/// <param name="fp">format provider</param>
	/// <returns>The parsed value, will throw an exception if the parsing faile</returns>
	public static T Parse<T>(this string input, IFormatProvider? fp = null)
	  where T : ISpanParsable<T>
	{
		return T.Parse(input, fp);
	}

	/// <summary>
	/// Parse a string for a given type <typeparamref name="T"/>, the parsed value is returned as an out parameter
	/// </summary>
	/// <typeparam name="T">Type that supports an ISpanParsable<typeparamref name="T"/> interface</typeparam>
	/// <param name="input">string to parse</param>
	/// <param name="fp">format provider</param>
	/// <returns>whether the parse succeeded or not</returns>
	public static bool TryParse<T>(this string input, IFormatProvider fp, out T? value)
	  where T : ISpanParsable<T>
	{
		return T.TryParse(input, fp, out value);
	}

	/// <summary>
	/// Parse a string for a given type <typeparamref name="T"/>
	/// </summary>
	/// <typeparam name="T">Type that supports an ISpanParsable<typeparamref name="T"/> interface</typeparam>
	/// <param name="input">string to parse</param>
	/// <param name="defaultValue">The value to return if the parsing failed</param>
	/// <returns>The parsed value if the string was successfully parsed, the default value otherwise</returns>
	public static T Parse<T>(this string input, T defaultValue)
	  where T : ISpanParsable<T>
	{
		T result = T.TryParse(input, null, out T? value) ? value : defaultValue;
		return result;
	}
}

Here are some examples on how to call them. I have used the Shouldy package to perform the assertions.

int resSpan = "  54 ".AsSpan().Parse(); // Span Parse
resSpan.ShouldEqual(54);

int resStr = " 27  ".Parse();   // String parse
resStr.ShouldEqual(27);
	
var action = () => { int res2Str = "   ".Parse(); }; // String parse that throws a format exception
action.ShouldThrow(); 

int res2Span = "   ".AsSpan().Parse(-1); // Span parse with default value
res2Span.ShouldEqual(-1);