如何将ICustomFormatter添加到默认格式化程序?

时间:2016-06-05 10:05:43

标签: c# string string-formatting

string.Format方法支持多种默认格式,并允许您在必要时指定自定义格式提供程序。

但是有没有办法注册ICustomFormatter,以便在不使用重载并明确指定的情况下自动选择它?

string.Format("foo {0:bar} baz", "qux");

我希望Format能够找到barFormatter

class barFormatter : IFormatProvider, ICustomFormatter {}

无需写:

string.Format(new barFormatter(), "foo {0:bar} baz", "qux");

编辑:

这是我到目前为止最接近的:

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();
        }
    }
}

示例:

string.Format(
    new ExtendableFormatter(),
    "foo {0:U} baz {1,-5:f1} {2:ddMMMyy}",
    "qux", 1.234f, DateTime.Now).Dump();

结果:

  

foo QUX baz 1.2 05Jun16

我猜测没有其他方法可以解决它,但使用像这样的自定义格式化程序?

1 个答案:

答案 0 :(得分:0)

我通过实现复合格式化器解决了这个问题。完整的代码可以在Custom string formatters下的代码审核中找到。