While browsing the latest .NET news and videos, I came across a video titled “C# interview questions What is the difference between convert.tostring and tostring ().” I typically use ToString when I must, as null references are usually defined away in my code contracts. I watched the video, interested if there was more to Convert.ToString than meets the eye.
For a basic interview video, it provides the information you need: Convert can handle nulls. But that’s not good enough for me. I want to know if there’s anything deeper, because if I need a string representation it’s generally for a value type, not a reference type… and the question of a null reference is inconsequential.
I fired up JustDecompile, opened mscorlib, then analyzed Object.ToString().
public virtual string ToString()
{
return this.GetType().ToString();
}
Unless you override the ToString method, the type name is returned. Reference types have an issue with null reference exceptions as methods (aside from extension methods) can’t be called when the reference is null.
Convert.ToString(obj), on the other hand, is a static method on a static class. It can be called at anytime, passing the reference (or value) as a parameter.
public static string ToString(object value)
{
return Convert.ToString(value, null);
}
public static string ToString(object value, IFormatProvider provider)
{
IConvertible convertible = value as IConvertible;
if (convertible != null)
{
return convertible.ToString(provider);
}
IFormattable formattable = value as IFormattable;
if (formattable != null)
{
return formattable.ToString(null, provider);
}
if (value != null)
{
return value.ToString();
}
return string.Empty;
}
Convert.ToString does exhibit behavior beyond what is mentioned in the video. It prefers specific interfaces (IConvertible and IFormattable), and it will call the explicit ToString methods of those interfaces first. Here’s how you can set it up.
public static class Program
{
private static void Main(string[] args)
{
Formattable formattable = new Formattable();
Console.WriteLine(formattable.ToString());
Console.WriteLine(Convert.ToString(formattable));
}
public class Formattable : IFormattable
{
string IFormattable.ToString(string format, IFormatProvider formatProvider)
{
return "Called IFormattable.ToString";
}
public override string ToString()
{
return "Called Overridden ToString";
}
}
}
Run this program for yourself, and you will find that Convert.ToString does more than handle nulls. But there’s more! The typical call to Convert.ToString will return String.Empty if the parameter is null. In the video, this example is given.
string str = null;
str = Convert.ToString(str);
Convert.String(str) calls a particular overload which is essentially an identity call.
public static string ToString(string value)
{
return value;
}
The value will still be null in the given example.
The video I linked to and others like it have value for those seeking to understand how the .NET world and C# operate. Deeper knowledge can always be gained by decompiling and testing the .NET framework. You never know what you may find.