对于IFormattable参考实现(Reference Implementation for IF

2019-08-06 02:00发布

是否有一个良好的参考实现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);
    }
}

但它好像有应该涵盖的其他潜在的情况,即:

  1. 如果formatProvider是空的,我应该回落到this.ToString()
  2. 如果formatProvider.GetFormat(typeof(ICustomFormatter))返回null ,是有什么特别的例外,我应该抛出?

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

Answer 1:

你似乎误解了.NET Framework的格式化基础设施的设计。 ICustomFormatter不应该的实现内部参考IFormattable.ToString ,因为这与该接口的预期目的相冲突。

IFormattable

一个对象应该只实现IFormattable如果它知道如何格式化本身(理想情况下,应该委派到另一个类的课程,但这里会有故意耦合)。 一个对象可能知道如何格式化本身多种不同的方式,所以格式字符串允许您在它们之间进行挑选。 即使有可能仍然缺少的信息,这样的事情,通过文化的不同而不同。 因此存在间接提供这样的信息的第二参数。

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

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

实现IFormattable

因此,让我们想象一下,我们正在创造一些新的自我格式化类。 如果它知道只有一个办法,自己的格式,它应该简单地重写object.ToString()仅此而已。 如果该类知道格式化本身应该实行不止一种方法IFormattable

format参数

每文档的IFormattable.ToString的格式字符串"G" (其代表的一般格式) 必须得到支持。 建议在一个空值或空字符串格式等同于的格式串"G" 。 确切含义是否则取决于我们。

formatProvider参数

如果我们需要什么特定的文化,或否则将发生变化,我们需要利用IFormatProvider参数。 会有一些类型,我们使用请求来自它的IFormatProvider.GetFormat 。 如果IFormatProvider为空,或者如果IFormatProvider.GetFormat的类型返回null我们想要的,我们应该回落到一些默认源出于此不同的信息。

默认源不一定是静态的。 可以想象的是,默认的源可能是在应用程序的用户设置,并且formatProvider用于预览选项的改变和/或用于序列化时,需要一个固定的格式。

这也有可能是格式可能涉及到一些格式化子对象。 在这种情况下,你可能想传递IFormatProvider下来。 MSDN有一个很好的例子贯彻IFormattable ,显示这种非常情况下。

其他ToString重载

当实现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变得相关。 一个IFormatProvider能够提供ICustomFormatter类型可以为被传递IFormatProvider在类似的方法参数string.FormatStringBuilder.AppendFormat

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

参考

这个MSDN页面提供了.NET格式化系统的一个很好的概述,并提供链接到几乎所有MSDN中的其他相关网页。 这是开始于几乎任何格式相关的问题的最佳场所。



Answer 2:

对于这些问题的一个很好的信息可以在里面找到单声道的源代码。 你可能会发现它在这里面,有不少用途mscorlib.dll中的代码。



文章来源: Reference Implementation for IFormattable