The following example shows how to write a custom IFormatProvider which you can use in String.Format(IFormatProvider, ...).
public class DoubleFormatter : IFormatProvider, ICustomFormatter
{
// always use dot separator for doubles
private CultureInfo enUsCulture =
CultureInfo.GetCultureInfo("en-US");
public string Format(string format, object arg,
IFormatProvider formatProvider)
{
// format doubles to 3 decimal places
return string.Format(enUsCulture, "{0:0.000}", arg);
}
public object GetFormat(Type formatType)
{
return (formatType == typeof(ICustomFormatter))
? this : null;
}
}
Having this formatter, we can use it like this:
double width = 15.77555;
double height = 12.8497979;
Console.WriteLine(
string.Format(new DoubleFormatter(), "w={0} h={1}", width, height));
Output:
So now we have a reusable format for doubles - 3 decimal places with dot separator. That is nice, but this formatter is very simple - it formats
everything (eg. DateTime) as "0:000". This is a fast version if you know that you will only use it for formatting lots of doubles.
The real version should look like this:
public class DoubleFormatter : IFormatProvider, ICustomFormatter
{
// always use dot separator for doubles
private CultureInfo enUsCulture =
CultureInfo.GetCultureInfo("en-US");
public string Format(string format, object arg,
IFormatProvider formatProvider)
{
if (arg is double)
{
if (string.IsNullOrEmpty(format))
{
// by default, format doubles to 3 decimal places
return string.Format(enUsCulture, "{0:0.000}", arg);
}
else
{
// if user supplied own format use it
return ((double)arg).ToString(format, enUsCulture);
}
}
// format everything else normally
if (arg is IFormattable)
return ((IFormattable)arg).ToString(format, formatProvider);
else return arg.ToString();
}
public object GetFormat(Type formatType)
{
return (formatType == typeof(ICustomFormatter)) ? this : null;
}
}
Example:
Console.WriteLine(string.Format(new DoubleFormatter(),
"Numbers {0} and {1:0.0}." +
"Now a string {2}, a number {3}, date {4} and object: {5}",
1.234567, -0.57123456, "Hi!", 5, DateTime.Now, new object()));
Output:
Numbers 1.235 and -0.6. Now a string Hi!, a number 5, date 12.6.2009 17:11:35 and object: System.Object
This article should give you an overview of implementing custom IFormatProvider. Now you should be able to modify the code to suit your specific needs.
Other examples with custom formatters can be found in MSDN. See example with
formatter for 12-digit account numbers (12345–678–9012).