IFormattable的参考实施

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

到目前为止我所拥有的:

 public class MyDataClass : IFormattable { ///  public string ToString(string format, IFormatProvider formatProvider) { ICustomFormatter formatter = (ICustomFormatter)formatProvider.GetFormat(typeof(ICustomFormatter)); return formatter.Format(format, this, formatProvider); } } 

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

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

任何博客文章/代码示例/ MSDN引用表示赞赏。

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

IFormattable

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

传递给IFormatProvider.GetFormat的类型旨在成为特定于提供IFormatProvider的类的类型或接口。

例如,内置数字类型希望能够检索System.Globalization.NumberFormatInfo的实例,而DateTime相关类希望能够检索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 ,重要的是以等效于以下的方式覆盖IFormattable Object.ToString()

 public override string ToString() { return this.ToString(null, System.Globalization.CultureInfo.CurrentCulture); } 

这样做可以确保somestring + yourobject等同于string.Format("{0}{1}",somestring, yourobject) ,您的用户可能会认为这是真的。

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

ICustomFormatter

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

提供的ICustomFormatterstring.Format执行的每个格式化调用了Format方法。 如果ICustomFormatter不熟悉所使用的格式字符串或者不支持该类型,则只需委托给IFormattable.ToStringIFormattable.ToStringICustomFormatter文档提供了一个列表,列出了在格式化尚未提供格式支持的对象时所需的内容,以及如果您只想在现有IFormattable添加额外格式IFormattable 。 它还提供了添加额外格式案例的示例。

参考

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

对于这些问题,可以在Mono源代码中找到良好的信息源。 您可能会在其mscorlib.dll代码中找到相当多的用法。