IFormattable的参考实施

Sco*_*ner 13 .net c# iformattable

IFormattable有一个很好的参考实现吗?我打算IFormatProvider为我的对象至少有一个自定义,我想确保传递给不同的可能参数集的连线正确IFormattable.ToString(string, IFormatProvider).

到目前为止我所拥有的:

public class MyDataClass : IFormattable
{
    /// <seealso cref="IFormattable.ToString(string, IFormatProvider)"/>
    public string ToString(string format, IFormatProvider formatProvider)
    {
        ICustomFormatter formatter = (ICustomFormatter)formatProvider.GetFormat(typeof(ICustomFormatter));
        return formatter.Format(format, this, formatProvider);
    }
}
Run Code Online (Sandbox Code Playgroud)

但似乎应该涵盖其他潜在的情况,即:

  1. 如果formatProvider为null,我应该回归this.ToString()吗?
  2. 如果formatProvider.GetFormat(typeof(ICustomFormatter))返回null,是否应该抛出一个特殊的异常?

欢迎任何博客文章/代码示例/ MSDN参考.

Kev*_*art 39

您似乎误解了.NET Framework格式化基础结构的设计.ICustomFormatter永远不应该在实现中引用IFormattable.ToString,因为它与该接口的预期目的冲突.

IFormattable

一个对象应该只IFormattable在它知道如何格式化自己时实现(理想情况下它应该将它委托给另一个类当然,但这里会有故意的耦合).对象可能知道如何以多种不同的方式格式化自己,因此格式字符串允许您在它们之间进行选择.即使这样,可能仍然缺少信息,这些因文化而异.因此,存在间接提供这种信息的第二参数.

传递给的类型IFormatProvider.GetFormat是特定IFormatProvider于提供给它的类的类型或接口.

例如,内置数字类型希望能够检索实例System.Globalization.NumberFormatInfo,而DateTime相关类希望能够检索a System.Globalization.DateTimeFormatInfo.

实施 IFormattable

因此,让我们假设我们正在创建一些新的自我格式化类.如果它只知道一种格式化的方法,它应该简单地覆盖object.ToString(),仅此而已.如果类知道不止一种格式化的方法应该实现IFormattable.

format参数

每个文档IFormattable.ToString格式字符串"G"(代表一般格式)必须被支持.建议null或空格式字符串等效于格式字符串"G".确切的含义取决于我们.

formatProvider参数

如果我们需要任何特定的文化,或者否则我们需要使用该IFormatProvider参数.会有一些我们要求它使用的类型IFormatProvider.GetFormat.如果IFormatProvider为null,或者IFormatProvider.GetFormat对于我们想要的类型返回null,我们应该回退到这个变化信息的某个默认源.

默认源不必是静态的.可以想象,默认源可以是应用程序中的用户设置,并且formatProvider用于预览选项更改和/或何时需要固定格式进行序列化.

格式化也可能涉及格式化某些子对象.在那种情况下,你可能想要传递IFormatProvider下来.MSDN有一个很好的实现示例IFormattable,显示了这种情况.

其他ToString超载

在实施时IFormattable,重要Object.ToString()的是以与以下相同的方式覆盖

public override string ToString()
{
    return this.ToString(null, System.Globalization.CultureInfo.CurrentCulture);
}
Run Code Online (Sandbox Code Playgroud)

这样做可以确保somestring + yourobject等同于string.Format("{0}{1}",somestring, yourobject)您的用户期望的真实性.

为方便您的用户,您应该提供string ToString(string format).此外,如果您的默认格式包含可以从中受益的任何不同组件IFormatProvider,您可能还需要提供public string ToString(IFormatProvider provider).

ICustomFormatter

那么如果我们想要格式化一个不知道如何格式化自己的类,或者我们想要使用类本身不支持的某种格式,我们该怎么做呢.这就是ICustomFormatter变得相关的地方.一个IFormatProvider能够提供ICustomFormatter类型可以作为被传递IFormatProvider在类似方法参数string.FormatStringBuilder.AppendFormat.

提供的每个格式ICustomFormatter都有其Format调用的方法string.Format.如果ICustomFormatter不熟悉使用的格式字符串或者不支持该类型,则只需委托给IFormattable.ToStringObject.ToString.该ICustomFormatter文件提供的,如果要格式化的对象已经不提供格式化的支持,并且需要什么,如果你只是想要一个额外的格式添加到现有的所需要的清单IFormattable.它还提供了添加额外格式案例的示例.

参考

此MSDN页面提供了.NET格式化系统的完整概述,并提供了指向MSDN中几乎所有其他相关页面的链接.这是几乎任何格式相关问题的最佳起点.

  • 感谢您的详细解答和参考! (2认同)
  • 当我第一次阅读这个问题时,我基本上对所有这些问题感到困惑,所以我看了反射器中的框架,并开始阅读MSDN页面,我只是更加困惑.在我找到主要参考页面之前,我已经阅读了大部分MSDN页面.即便如此,它还需要一段时间才能开始点击.有一些棘手的部分.例如,我怀疑`ICustomFormatter`与IFormatProvider一起使用的唯一原因是因为它是1.0框架的后期添加,并且他们不想添加新的`string.Format`重载. (2认同)