C#:IFormattable,IFormatProvider和ICustomFormatter之间的连接,以及何时使用什么

Svi*_*ish 36 c# formatting

有什么区别和之间的连接IFormattable,IFormatProvider并且ICustomFormatter当他们会使用吗?一个简单的实现示例也非常好.

我并不是故意在.net框架中使用它,但是当我自己实现这些时,在这种情况下,哪些类通常会实现什么接口以及如何正确地执行它.

Bar*_*lly 37

  • IFormattable是一个支持格式的对象string.Format,即xxxin {0:xxx}.如果对象支持接口,string.Format则委托给对象的IFormattable.ToString方法.

  • IFormatProvider 是格式化程序用于特定于文化的日期和货币布局等配置信息的来源.

  • 然而,对于例如像的情况DateTime,在那里你要格式化的情况下已经实现了IFormattable,你却不控制实现(DateTimeBCL中提供,你不能轻易取代它),有一种机制,以防止string.Format从简单地使用IFormattable.ToString.相反,您实现IFormatProvider,并在被要求ICustomFormatter实现时,返回一个.string.FormatICustomFormatter提交者委托给对象之前检查提供者IFormattable.Format,这反过来可能会询问IFormatProvider特定于文化的数据CultureInfo.

这是一个程序,它显示了string.Format要求的内容IFormatProvider,以及控制流程如何:

using System;
using System.Globalization;

class MyCustomObject : IFormattable
{
    public string ToString(string format, IFormatProvider provider)
    {
        Console.WriteLine("ToString(\"{0}\", provider) called", format);
        return "arbitrary value";
    }
}

class MyFormatProvider : IFormatProvider
{
    public object GetFormat(Type formatType)
    {
        Console.WriteLine("Asked for {0}", formatType);
        return CultureInfo.CurrentCulture.GetFormat(formatType);
    }
}

class App
{
    static void Main()
    {
        Console.WriteLine(
            string.Format(new MyFormatProvider(), "{0:foobar}", 
                new MyCustomObject()));
    }
}
Run Code Online (Sandbox Code Playgroud)

它打印这个:

Asked for System.ICustomFormatter
ToString("foobar", provider) called
arbitrary value
Run Code Online (Sandbox Code Playgroud)

如果更改格式提供程序以返回自定义格式化程序,则它将接管:

class MyFormatProvider : IFormatProvider
{
    public object GetFormat(Type formatType)
    {
        Console.WriteLine("Asked for {0}", formatType);
        if (formatType == typeof(ICustomFormatter))
            return new MyCustomFormatter();
        return CultureInfo.CurrentCulture.GetFormat(formatType);
    }
}

class MyCustomFormatter : ICustomFormatter
{
    public string Format(string format, object arg, IFormatProvider provider)
    {
        return string.Format("(format was \"{0}\")", format);
    }
}
Run Code Online (Sandbox Code Playgroud)

运行时:

Asked for System.ICustomFormatter
(format was "foobar")
Run Code Online (Sandbox Code Playgroud)