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?
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.