Converting Strings to .NET Objects – IParsable and ISpanParsable

A new feature of C# 11 allows abstract static members with interfaces. This makes it possible to define class methods to be used as a contract with a generic class implementation, e.g. using + and – operators. With .NET 7, numeric types implement many new interfaces. This C# 11 feature is not only about math! The new IParsable and ISpanParsable interfaces allow creating objects from strings. As these interfaces can be used with constraints in generic types, parsing strings to create objects is now an easy task with generic implementations. This article shows implementing both the string and the Span version of the parse interfaces and using them with generic types.

Parse strings to objects

IFormattable

Let’s start with an interface which is not new but covers the other side of parsing from a string: converting the object to a string. The IFormattable interface is available since the early days of .NET. Contrary to the parsable interface, the members defined in the IFormattable interface are instance members.

With the sample code, the ColorResult record is split across multiple files using the partial keyword. In one file, the members of the ColorResult are defined as shown in the following code snippet. The other files defining the ColorResult type implement the needed interfaces. ColorResult contains two byte values. Depending on the game type, the maximum number is different. With the existing game types, these values are in a range from 0 to 5.

ColorResult record

With the following implementation of the IFormattable interface, a string is returned to contain both values from the record. The IFormattable interface specifies parameters for format strings and cultures. With the ColorResult implemented, different format strings are not used, and there’s no difference based on the culture, that’s why the parameters are ignored.

IFormattable implementation

ISpanFormattable

To avoid creating new objects that need to be garbage collected, the ISpanFormattable interface is available since .NET 6. This interface allows writing the string representation of an object to a Span instance. The following code snippet shows the implementation of the ISpanFormattable interface. If the size of the span is not big enough, the TryFormat implementation returns false. Otherwise, the numbers with a separator are written to the span:

ISpanFormattable implementation

The IFormattable interface implementation is now changed to use the span version by allocating a character array with the required size, and pass a Span referencing this array to the TryFormat method:

Using the ISpanFormattable implementation from ToString

IParsable and ISpanParsable

To create a new object from the string representation, the interfaces IParsable and ISpanParsable are available with .NET 7. These interfaces define static abstract members to convert a string and a span to the generic type as shown in the following code snippets:

IParsable interface

ISpanParsable interface

You might wonder about the NotNullWhen and the MaybeNullWhen attributes. These attributes are used to tell the compiler that the method returns true if the object is not null, and false if the object is null. The compiler uses this information to avoid null checks. With the TryParse method, the MaybeNullWhen attribute is used to tell the compiler that the object is null if the method returns false. The NotNullWhen attribute specifies that the parameter is not null the return value is true. This parameter is not an output of this method, so why is this important? With this, the compiler knows, after this method returned successfully, null checks are not requires when the variable is used again.

Implementing ISpanParsable

The ToString method returns a string containing the members of the ColorType separated by a colon. Using the list pattern that is available since C# 10 with pattern matching, with the following code snippet, if the pattern matches two characters sparated by a colon, a new ColorField instance is created and returned. Otherwise, the method returns null:

Implementing ISpanParsable

Using ISpanParsable

With this implementation, a generic method can be implemented to use any type which implements the IParsable interface. With the generic extension method AddMove, a constraint is defined to require the IParsable to be implemented with the generic type TResult. Then, using the class name TResult, the Parse method can be called. With the following code snippet some test string values are passed for parsing and creating a new ColorField instance. With the game implementation, an algorithm is called get get the correct string values based on the move and the game type:

Using ISpanParsable

Other Implementations

You might be interested in how ISpanParsable is implemented for the existing types. The following code snippet shows the implementation for the IPAddress type. The TryParse method is used to parse a span to an IPAddress instance. The implementation makes use of the IPAddressParser.Parse method. The implemenation of this method checks if a : is present in the span, and if so, the span is parsed as an IPv6 address. Otherwise, the span is parsed as an IPv4 address. If the parsing fails, the implementation checks if the method with the Try prefix is used where null is returned, and otherwise throws a FormatException. The implementation of the method IP4StringToAddress to create a long type to represent the IP address which is in turn used to instantiate an IPAddress instance is shown in the following code snippet:

IPv4 Address parsing

> As you can see with the IPAddress parsing implementation, using unsafe code with C# and Span types can be of practical use. With the implementation of the ColorResult type where the values are just written to different bytes, the use of unsafe code is not required. In cases like the IPAddress type to convert the span to an int, it can increase performance what can be of great advantage when you convert many instances in your application.

Take away

Creating a generic implementation to create instances of can now easily be done with the IParsable and ISpanParsable interfaces. For the other way around, to convert an object to a string or a span, use the IFormattable and ISpanFormattable interfaces. The ISpanFormattable interface is available since .NET 6, and the IParsable and ISpanParsable interfaces are available since .NET 7.

Enjoy learning and programming!

Christian

If you like this article, please support me with a coffee. Thanks!

Buy Me A Coffee

More Information

The source code of this article is available int the Professional C# book repo within 5_More/Services as part of the MinimalAPIWithGroupsAndTypedResults sample.

More information about C# programming is available in my book and my workshops.

IPAddress Implementation

Professional C# source code

Read more about C# in my book Professional C# and .NET – 2021 Edition

Trainings

The top image was created using Microsoft Bing Image Creator powered by DALL-E.

Advertisement

8 thoughts on “Converting Strings to .NET Objects – IParsable and ISpanParsable

  1. > The MaybeNullWhen attribute is used to tell the compiler that the object is null if the method returns false. The compiler uses t
    Don’t leave us hanging! What does the compiler use?
    My brain is singing “What does the compiler use?” and answering with “Ring-ding-ding-ding-dingeringeding”, which probably isn’t what you intended.

    Like

  2. Can’t tell if it took the earlier comment or not… can’t see it, but AIA if there are two now.

    > The compiler uses this information to avoid null checks. The MaybeNullWhen attribute is used to tell the compiler that the object is null if the method returns false. The compiler uses t

    What comes next? You’ve left me hanging! Or is it just starting the beginning of this quote over again?

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.