首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#:IFormattable、IFormatProvider和ICustomFormatter之间的连接,以及何时使用what

C#:IFormattable、IFormatProvider和ICustomFormatter之间的连接,以及何时使用what
EN

Stack Overflow用户
提问于 2009-11-09 02:38:45
回答 3查看 8.7K关注 0票数 38

IFormattableIFormatProviderICustomFormatter之间有什么区别和联系?什么时候使用它们?一个简单的实现示例也会非常好。

我指的不是什么时候在.net框架中使用它,而是我自己什么时候实现它们,在这种情况下,哪些类通常会实现什么接口,以及如何正确地实现这些接口。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-11-09 03:10:51

  • IFormattable是一个支持string.Format格式的对象,即{0:xxx}中的xxx。如果对象支持interface.
  • IFormatProvider是格式器用于特定文化的日期和货币layout.
  • However,的配置信息源,string.Format将委托给对象的IFormattable.ToString方法。例如,在像DateTime这样的情况下,你想格式化的实例已经实现了IFormattable,但你不能控制实现(DateTime是在BCL中提供的,你不能轻易地替换它),有一种机制可以防止string.Format简单地使用IFormattable.ToString。相反,您可以实现IFormatProvider,当请求ICustomFormatter实现时,返回一个。在将ICustomFormatter委托给对象的IFormattable.Format之前,string.Format会检查提供者是否有ICustomFormatter,这反过来可能会向IFormattable.Format请求特定于文化的数据,如string.Format

下面是一个程序,它显示了string.FormatIFormatProvider请求什么,以及控制流程是如何进行的:

代码语言:javascript
复制
using System;
using System.Globalization;

class MyCustomObject : IFormattable
{
    public string ToString(string format, IFormatProvider provider)
    {
        Console.WriteLine("ToString(\"{0}\", provider) called", format);
        return "arbitrary value";
    }
}

class MyFormatProvider : IFormatProvider
{
    public object GetFormat(Type formatType)
    {
        Console.WriteLine("Asked for {0}", formatType);
        return CultureInfo.CurrentCulture.GetFormat(formatType);
    }
}

class App
{
    static void Main()
    {
        Console.WriteLine(
            string.Format(new MyFormatProvider(), "{0:foobar}", 
                new MyCustomObject()));
    }
}

它打印以下内容:

代码语言:javascript
复制
Asked for System.ICustomFormatter
ToString("foobar", provider) called
arbitrary value

如果格式提供程序更改为返回自定义格式化程序,它将接管:

代码语言:javascript
复制
class MyFormatProvider : IFormatProvider
{
    public object GetFormat(Type formatType)
    {
        Console.WriteLine("Asked for {0}", formatType);
        if (formatType == typeof(ICustomFormatter))
            return new MyCustomFormatter();
        return CultureInfo.CurrentCulture.GetFormat(formatType);
    }
}

class MyCustomFormatter : ICustomFormatter
{
    public string Format(string format, object arg, IFormatProvider provider)
    {
        return string.Format("(format was \"{0}\")", format);
    }
}

运行时:

代码语言:javascript
复制
Asked for System.ICustomFormatter
(format was "foobar")
票数 40
EN

Stack Overflow用户

发布于 2020-04-04 16:12:28

自定义格式基于3个组件之间的协调工作:

  • Formattable
  • Format provider
  • Formatter

可格式化对象是可以使用格式提供程序和格式字符串通过实现IFormattable接口来格式化其数据的实例。基本上,它们将请求格式提供程序获取formatter,然后使用格式字符串,格式字符串是请求formatter格式化其实例的格式指令。日期/时间和数字类型是可格式化类型的示例。

格式提供程序是实现IFormatProvider接口的类。它们负责根据调用者请求的格式类型返回formatter对象。格式类型可以是格式提供者可以理解的任何类型,而返回的formatter应该是调用者(大多数情况下是可格式化的对象)可以用来格式化数据的任何类型。

格式化程序是负责提供格式化服务的对象。对于日期/时间和数字类型,格式提供程序也是formatters,它们是CultureInfoDateTimeFormatInfoNumberFormatInfo

在由某些方法(如String.FormatConsole.WriteLineStringBuilder.AppendFormat )实现的复合格式化中,当格式提供程序被传递给它们时,它们总是向格式提供程序请求实现ICustomFormatter接口的formatter。这允许开发人员为这些方法提供各种自定义格式。

票数 2
EN

Stack Overflow用户

发布于 2009-11-09 03:08:00

IFormattable是一个支持不同(命名/自定义)格式的对象,例如数字等。通过使用一个接口,多个代码块可以使用值和格式字符串,这在数据绑定和string.Format中很常见(例如)。

IFormatProvider填补了格式化方面的一些空白--尤其是i18n。最常见的是,CultureInfo被用作提供者,要么提供特定的本地格式,要么提供不变的区域性。

据我所知,ICustomFormatter是无关的,它更多地与序列化(BinaryFormatter)联系在一起。我可能错了..。

IFormattable对象的示例:

代码语言:javascript
复制
IFormattable d = 123.45M;
string s1 = d.ToString("c", CultureInfo.CurrentCulture), // local currency
       s2 = d.ToString("c", CultureInfo.InvariantCulture); // invariant currency
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1697470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档