I think the example can be improved. After all, the ToString() method should use the given FormatProvider information for its rendering. So, everytime it calls to x.ToString(), y.ToString() or String.Format, all the items should be formatted using the argument fp. I think the following example is better (I have used double values so you can see the differences):
class Point : IFormattable
{
public double x, y;
public Point (double x, double y)
{
this.x = x;
this.y = y;
}
public override String ToString () { return ToString (null, null); }
public String ToString (String format, IFormatProvider fp)
{
// If no format is passed, display like this: (x, y).
if (format == null)
return String.Format ("({0}, {1})", x.ToString (fp), y.ToString (fp));
// For "x" formatting, return just the x value as a string
if (format == "x")
return x.ToString (fp);
// For "y" formatting, return just the y value as a string
if (format == "y")
return y.ToString (fp);
// For any unrecognized format, throw an exception.
throw new FormatException (String.Format ("Invalid format string: '{0}'.", format));
}
}
If you call it like this:
Point x = new Point (3.3, 5);
Debug.WriteLine (x.ToString (null, CultureInfo.InvariantCulture));
Debug.WriteLine (x.ToString (null, CultureInfo.GetCultureInfo ("es-ES")));
then you will see the difference:
(3.3, 5)
(3,3, 5)
By the way, I am still not happy, as we are hardcoding the comma as list separator; that separator is also culture-dependent, and theoretically it could be retrieved. However I don't know how to get that value from the IFormatProvider object...
In any case, for integer values it does not matter if the IFormatProvided argument is used or not - so the given example is indeed right for integers. But I think it is worth to notice this point.