I tried to make an extension method which still preserves the IFormattable
support. It uses a nested class which remembers the raw value and the desired width. Then when format string is provided, it is used, if possible.
It looks like this:
public static class MyExtensions
{
public static IFormattable Center<T>(this T self, int width)
{
return new CenterHelper<T>(self, width);
}
class CenterHelper<T> : IFormattable
{
readonly T value;
readonly int width;
internal CenterHelper(T value, int width)
{
this.value = value;
this.width = width;
}
public string ToString(string format, IFormatProvider formatProvider)
{
string basicString;
var formattable = value as IFormattable;
if (formattable != null)
basicString = formattable.ToString(format, formatProvider) ?? "";
else if (value != null)
basicString = value.ToString() ?? "";
else
basicString = "";
int numberOfMissingSpaces = width - basicString.Length;
if (numberOfMissingSpaces <= 0)
return basicString;
return basicString.PadLeft(width - numberOfMissingSpaces / 2).PadRight(width);
}
public override string ToString()
{
return ToString(null, null);
}
}
}
Note: You have not indicated if you want the one "extra" space character put to the left or to the right in cases where an odd number of space characters needs to be appended.
This test seems to indicate it works:
double theObject = Math.PI;
string test = string.Format("Now '{0:F4}' is used.", theObject.Center(10));
Of course, format string F4
with a double
means "round to 4 decimal places after the decimal point".