IFormattable的参考实现 [英] Reference Implementation for IFormattable
问题描述
IFormattable 是否有很好的参考实现?我计划为我的对象至少有一个自定义 IFormatProvider
,并且我想确保对于传递给 IFormattable.ToString(string,IFormatProvider)的不同可能参数集,接线正确无误.
.
Is there a good reference implementation for IFormattable? I plan to have at least one custom IFormatProvider
for my object, and I want to make sure that the wiring is correct for the different possible parameter sets passed to IFormattable.ToString(string, IFormatProvider)
.
到目前为止我所拥有的:
What I have so far:
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);
}
}
但是似乎还有其他可能的情况,即:
But it seems like there are other potential situations that should be covered, i.e.:
- 如果
formatProvider
为null,我应该退回到this.ToString()
吗? - 如果
formatProvider.GetFormat(typeof(ICustomFormatter))
返回null
,我应该抛出一个特殊的异常吗?
- If
formatProvider
is null, should I fall back tothis.ToString()
? - If
formatProvider.GetFormat(typeof(ICustomFormatter))
returnsnull
, is there a particular exception I should throw?
感谢任何博客文章/代码示例/MSDN参考.
Any blog posts / code samples / MSDN references are appreciated.
推荐答案
您似乎误解了.NET Framework格式基础结构的设计. ICustomFormatter
绝不能在 IFormattable.ToString
的实现内引用,因为这与该接口的预期目的相冲突.
You seem to misunderstand the design of the .NET Framework's formatting infrastructure. ICustomFormatter
should never be referenced inside an implementation of IFormattable.ToString
, since that clashes with the intended purpose of that interface.
如果对象知道如何格式化自身,则该对象仅应实现 IFormattable
(理想情况下,当然应将其委托给另一个类,但此处将有意地进行耦合).一个对象可能知道如何以多种不同的方式格式化自身,因此格式字符串允许您在它们之间进行选择.即使有可能仍然缺少信息,但这些信息因文化而异.因此,存在第二个参数间接提供此类信息.
An object should only implement IFormattable
if it knows how to format itself (ideally it should delegate that to another class of course, but there would be deliberate coupling here). An object may know how to format itself multiple different ways, so the format string allows you to pick between them. Even with that there may still be missing information, such things that vary by culture. Therefore there is a second parameter that provides such information indirectly.
传递给 IFormatProvider.GetFormat
的类型旨在是特定于提供 IFormatProvider
的类的类型或接口.
The type passed to IFormatProvider.GetFormat
is intended to be a type or interface specific to the class the IFormatProvider
was provided to.
例如,内置数字类型希望能够检索 System.Globalization.NumberFormatInfo
的实例,而与 DateTime
相关的类希望能够检索 System.Globalization.DateTimeFormatInfo
.
For example, the built-in numeric types want to be able to retrieve an instance of System.Globalization.NumberFormatInfo
, while the DateTime
related classes want to be able to retrieve a System.Globalization.DateTimeFormatInfo
.
因此,让我们想象一下我们正在创建一些新的自格式化类.如果它仅知道一种格式化自身的方法,则应仅覆盖 object.ToString()
,仅此而已.如果该类知道格式化自己的多种方法,则应实现 IFormattable
.
So let's imagine we are creating some new self-formatting class. If it knows only one way to format itself, it should simply override object.ToString()
, and nothing more. If the class knows more than one way to format itself should implement IFormattable
.
每个 IFormattable.ToString
的文档文档>必须支持 的"G"
格式字符串.建议将空字符串或空格式字符串与"G"
的格式字符串等效.确切的含义取决于我们.
Per the documentation of IFormattable.ToString
the format string of "G"
(which represents the general format) must be supported. It is recommended that a null or empty format string be equivalent to a format string of "G"
. The exact meaning is otherwise up to us.
如果我们需要任何特定于区域性的文化,或者可能会有所不同,则需要使用 IFormatProvider
参数.我们会使用 IFormatProvider.GetFormat
从中请求某些类型.如果 IFormatProvider
为null,或者如果 IFormatProvider.GetFormat
对于我们想要的类型返回null,则我们应该退回到某个默认源以获取这种变化的信息.
If we need anything culture specific, or that would otherwise vary we need to utilize the IFormatProvider
parameter. There would be some type that we request from it using IFormatProvider.GetFormat
. If the IFormatProvider
is null, or if IFormatProvider.GetFormat
returns null for the type we want we should fall back to some default source for this varying information.
默认来源不必是静态的.可以想象默认来源可能是应用程序中的用户设置,并且 formatProvider
用于预览选项更改和/或在需要固定格式进行序列化时使用.
The default source need not be static. It is conceivable that the default source might be a user setting in the app, and the formatProvider
is used to preview option changes and/or when a fixed format is needed for serialization.
格式化也可能涉及格式化某些子对象.在这种情况下,您可能希望向下传递 IFormatProvider
.MSDN有一个实现 IFormattable
的出色示例,它显示了这一点非常好.
It is also possible that formatting may involve formatting some sub-object. In that case you probably want to pass the IFormatProvider
down. MSDN has an excellent example of implementing IFormattable
that shows this very case.
在实现 IFormattable
时,以与以下等效的方式重写 Object.ToString()
很重要.
When implementing IFormattable
it is important that Object.ToString()
be overridden in a manner equivalent to the following
public override string ToString()
{
return this.ToString(null, System.Globalization.CultureInfo.CurrentCulture);
}
这样做可以确保 somestring + yourobject
等同于用户期望的 string.Format("{0} {1}",somestring,yourobject)
是真的.
Doing so ensures that somestring + yourobject
is equivalent to string.Format("{0}{1}",somestring, yourobject)
, which your users will expect to be true.
为了方便用户,您可能应该提供 string ToString(字符串格式)
.另外,如果您的默认格式具有可以从 IFormatProvider
中受益的任何不同组件,则可能还需要提供公共字符串ToString(IFormatProvider提供程序)
.
For the convenience of your users, you should probably provide string ToString(string format)
. Also if your default format has any varying components that can benefit from the IFormatProvider
, you may also want to provide public string ToString(IFormatProvider provider)
.
那么,如果我们要格式化一个不知道如何格式化自身的类,或者想要使用该类本身不支持的某种格式,该怎么办.这就是ICustomFormatter变得重要的地方.可以提供 ICustomFormatter
类型的 IFormatProvider
可以通过 string.Format
和 StringBuilder.AppendFormat
.
So what do we do if we want to format a class that does not know how to format itself, or we want to use some format not supported by the class itself. That is where ICustomFormatter becomes relevant. An IFormatProvider
that can provide the ICustomFormatter
type can be passed as the IFormatProvider
parameter in methods like string.Format
and StringBuilder.AppendFormat
.
所提供的 ICustomFormatter
具有其 Format
方法,该方法针对 string.Format
进行的每种格式调用.如果 ICustomFormatter
不熟悉所使用的格式字符串或不支持该类型的字符串,则只需将其委派给 IFormattable.ToString
或 Object.ToString
. ICustomFormatter
文档提供了以下列表:您正在格式化一个尚不提供格式化支持的对象,并且如果您只想向现有的 IFormattable
添加额外的格式,那将需要什么.它还提供了添加额外格式案例的示例.
The provided ICustomFormatter
has its Format
method called for each formatting that string.Format
does. If the ICustomFormatter
is unfamiliar with the format string used or has no support for that type it simply delegates to IFormattable.ToString
or Object.ToString
. The ICustomFormatter
documentation provides a list of what is needed if you are formatting an object that does not already provide formatting support, and what is needed if you merely want to add an extra format to an existing IFormattable
. It also provides an example of the adding an extra format case.
此MSDN页面提供了.NET格式系统的概述,并提供了链接到MSDN中几乎所有其他相关页面.几乎是所有与格式相关的问题的最佳起点.
This MSDN page provides a great overview of the .NET formatting system, and provides links to pretty much all the other relevant pages in MSDN. It is the best place to start for almost any formatting related question.
这篇关于IFormattable的参考实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!