Home > Blogs > Why no IParseable interface?

Why no IParseable interface?

By  Feb 26, 2008

Topics: Programming, Windows Programming

I found it curious that in the .NET Framework objects can implement the IFormattable interface to expose custom formatting, but there is no corresponding IParseable interface. Not only is this curious, it's somewhat frustrating. I was going to write a rant asking why the lack of IParseable and present a possible solution, and then I discovered the very good reason why such a thing hasn't been done.

Because all .NET classes inherit from System.Object, they all benefit from the overridable Object.ToString method. All of the .NET numeric types, for example, override ToString so that they can return a simple string representation of the number. In addition, all of the numeric types implement IFormattable, which allows for custom formatting: number styles, commas, number of decimal points, etc. Many other types also override ToString and implement IFormattable, making it very easy to write generic classes or methods for output that require the type to implement IFormattable. In general, outputting stuff is easy.

But input is more difficult. Numeric types (and dates) in .NET have always had a Parse method. But it's not a virtual method because the return type of Parse has to be the same as the implementing type, and you can't change the return type of an overridden method. That restriction also prevented an IParseable interface in .NET 1.x.

But the introduction of generics in .NET 2.0 made it possible to create generic interfaces, including interface methods whose return type is specified in the type parameter of the generic. That is, you can write:

interface IParseable<T>
    T Parse(string s);

If that's possible, then why not take the next step and implement IParseable for each of the numeric types? It would make so many things much easier!

Except that Parse and TryParse are static methods. It makes sense, right? If you want to create an int from a string, you write:

int i = string.Parse(s);

If Parse was an instance method, you'd have to create an instance of the underlying type in order to parse other integers. Your code would become:

int temp = 0; // dummy for parsing
int i = temp.Parse(s);

Nobody wants that! But a static method can't implement interface methods. That is, given the definition of IParseable above, the following won't compile:

class MyParseableThing : IParseable<MyParseableThing>
    static MyParseableThing Parse(string s)
        MyParseableThing result = null;
        // parsing code here
        return result;

You'll get an error saying that MyParseableThing.Parse cannot implement an interface member because it is static.

And that's why there is no IParseable interface. We need some other way to skin this particular cat.