IFormattable、IFormatProvider和ICustomFormatter之间有什么区别和联系?什么时候使用它们?一个简单的实现示例也会非常好。
我指的不是什么时候在.net框架中使用它,而是我自己什么时候实现它们,在这种情况下,哪些类通常会实现什么接口,以及如何正确地实现这些接口。
发布于 2009-11-09 03:10:51
IFormattable是一个支持string.Format格式的对象,即{0:xxx}中的xxx。如果对象支持interface.IFormatProvider是格式器用于特定文化的日期和货币layout.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.Format向IFormatProvider请求什么,以及控制流程是如何进行的:
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()));
}
}它打印以下内容:
Asked for System.ICustomFormatter
ToString("foobar", provider) called
arbitrary value如果格式提供程序更改为返回自定义格式化程序,它将接管:
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);
}
}运行时:
Asked for System.ICustomFormatter
(format was "foobar")发布于 2020-04-04 16:12:28
自定义格式基于3个组件之间的协调工作:
可格式化对象是可以使用格式提供程序和格式字符串通过实现IFormattable接口来格式化其数据的实例。基本上,它们将请求格式提供程序获取formatter,然后使用格式字符串,格式字符串是请求formatter格式化其实例的格式指令。日期/时间和数字类型是可格式化类型的示例。
格式提供程序是实现IFormatProvider接口的类。它们负责根据调用者请求的格式类型返回formatter对象。格式类型可以是格式提供者可以理解的任何类型,而返回的formatter应该是调用者(大多数情况下是可格式化的对象)可以用来格式化数据的任何类型。
格式化程序是负责提供格式化服务的对象。对于日期/时间和数字类型,格式提供程序也是formatters,它们是CultureInfo、DateTimeFormatInfo和NumberFormatInfo。
在由某些方法(如String.Format、Console.WriteLine或StringBuilder.AppendFormat )实现的复合格式化中,当格式提供程序被传递给它们时,它们总是向格式提供程序请求实现ICustomFormatter接口的formatter。这允许开发人员为这些方法提供各种自定义格式。
发布于 2009-11-09 03:08:00
IFormattable是一个支持不同(命名/自定义)格式的对象,例如数字等。通过使用一个接口,多个代码块可以使用值和格式字符串,这在数据绑定和string.Format中很常见(例如)。
IFormatProvider填补了格式化方面的一些空白--尤其是i18n。最常见的是,CultureInfo被用作提供者,要么提供特定的本地格式,要么提供不变的区域性。
据我所知,ICustomFormatter是无关的,它更多地与序列化(BinaryFormatter)联系在一起。我可能错了..。
IFormattable对象的示例:
IFormattable d = 123.45M;
string s1 = d.ToString("c", CultureInfo.CurrentCulture), // local currency
s2 = d.ToString("c", CultureInfo.InvariantCulture); // invariant currencyhttps://stackoverflow.com/questions/1697470
复制相似问题