Function with IFormattable parameter won't accept a String

I have a function where I processed a string input.

    public string Foo(string text)
    {
        // do stuff with text and
        // return processed string
    }

I was calling this from a lot of places where I was converting a guid to a string like this:

string returnValue = Foo(bar.ToString());

What I actually wanted was to accept as an input any object type that could be converted to a string. So I tried modifying the function as follows:

    public string Foo(IFormattable text)
    {
        var textAsString = text.ToString();
        // do stuff with textAsString 
        // and return processed string
    }

This means all my calls are simpler:

string returnValue = Foo(bar);

It works for all object types that have a .ToString method; Except strings :)

If I try passing a string to the function I get the following compile error:

Argument type 'string' is not assignable to parameter type 'System.IFormattable'  

Which seems really odd because String HAS a ToString() method.

Why doesn't this work?

Jon Skeet
people
quotationmark

Simply put, System.String doesn't implement IFormattable.

If the documentation isn't enough for you:

object x = "a string";
Console.WriteLine(x is IFormattable); // False

Given that ToString() is declared on object, why not just have:

public string Foo(object text)
{
    var textAsString = text.ToString();
    // do stuff with textAsString 
    // and return processed string
}

Indeed, the ToString() method declared by IFormattable isn't the one you were trying to call anyway - you weren't passing a format string or a format provider.

Additionally:

Which seems really odd because String HAS a ToString() method.

Interfaces aren't duck-typed. Just because a type has all the members required by an interface doesn't mean that it implements the interface.

people

See more on this question at Stackoverflow