IFormattable的参考实现 [英] Reference Implementation for IFormattable

查看:36
本文介绍了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.:

  1. 如果 formatProvider 为null,我应该退回到 this.ToString()吗?
  2. 如果 formatProvider.GetFormat(typeof(ICustomFormatter))返回 null ,我应该抛出一个特殊的异常吗?
  1. If formatProvider is null, should I fall back to this.ToString()?
  2. If formatProvider.GetFormat(typeof(ICustomFormatter)) returns null, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆