I needed a better string formatting options like ToUpper
and ToLower
but I also wanted to be able to use the default formattings so I created a custom formatter. It's main purpose is to support a template engine where the user should be able to use different formattings like upper or lower case. I still however couldn't figure out how to be make the date time upper case.
public class ExtendableFormatter : IFormatProvider, ICustomFormatter
{
public IDictionary<Type, IFormatProvider> FormatProviders { get; set; }
public ExtendableFormatter()
{
FormatProviders = new Dictionary<Type, IFormatProvider>
{
{ typeof(Byte), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(SByte), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(Int16), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(Int32), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(Int64), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(UInt16), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(UInt32), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(UInt64), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(Single), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(Double), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(Decimal), CultureInfo.InvariantCulture.NumberFormat },
{ typeof(DateTime), CultureInfo.InvariantCulture.DateTimeFormat },
{ typeof(String), new StringCaseFormatter() }
};
}
public object GetFormat(Type formatType)
{
return formatType == typeof(ICustomFormatter) ? this : null;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
var fp = (IFormatProvider)null;
if (FormatProviders.TryGetValue(arg.GetType(), out fp))
{
formatProvider = fp;
}
format = string.IsNullOrEmpty(format) ? string.Empty : ":" + format;
var result = string.Format(formatProvider, "{0" + format + "}", arg);
return result;
}
}
public class StringCaseFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
return formatType == typeof(ICustomFormatter) ? this : null;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
switch (format)
{
case "U": return arg.ToString().ToUpper();
case "L": return arg.ToString().ToLower();
default: return arg.ToString();
}
}
}
Example:
string.Format(
new ExtendableFormatter(),
"foo {0:U} baz {1,-5:f1} {2:ddMMMyy}",
"qux", 1.234f, DateTime.Now).Dump();
Result:
foo QUX baz 1.2 05Jun16