iformatable的参考实现
本文关键字:实现 参考 iformatable | 更新日期: 2023-09-27 17:51:05
是否有一个很好的iformatable参考实现?我计划为我的对象至少有一个自定义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);
}
}
但似乎还有其他潜在的情况应该包括在内,即:
- 如果
formatProvider
是空的,我应该回到this.ToString()
吗? - 如果
formatProvider.GetFormat(typeof(ICustomFormatter))
返回null
,是否有一个特殊的异常我应该抛出?
欢迎任何博客文章/代码示例/MSDN参考。
你似乎误解了。net框架的格式化基础结构的设计。ICustomFormatter
不应该在IFormattable.ToString
的实现中被引用,因为这与该接口的预期目的相冲突。
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
时,重要的是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.Format
和StringBuilder.AppendFormat
等方法中作为IFormatProvider
参数传递。
提供的ICustomFormatter
对string.Format
执行的每种格式化都调用Format
方法。如果ICustomFormatter
不熟悉所使用的格式字符串,或者不支持该类型,它只委托给IFormattable.ToString
或Object.ToString
。ICustomFormatter
文档提供了一个列表,列出了如果您要格式化一个尚未提供格式化支持的对象所需的内容,以及如果您只想向现有的IFormattable
添加额外的格式所需的内容。它还提供了一个添加额外格式大小写的示例。
这个MSDN页面提供了。net格式化系统的一个很好的概述,并提供了MSDN中几乎所有其他相关页面的链接。这是几乎所有与格式相关的问题的最佳起点。
标题>对于这样的问题,可以在Mono源代码中找到一个很好的源信息。您可能会在其mscorlib.dll代码中找到相当多的使用。