IFormattable
,IFormatProvider
和ICustomFormatter
之间的区别和联系以及它们何时被使用?一个简单的实现例子也会非常好。C#:IFormattable,IFormatProvider和ICustomFormatter之间的连接以及何时使用什么
我并不是真正意指它在.net框架中使用,但是当我自己实现这些时,那些类通常会实现什么接口以及如何正确执行它。
IFormattable
,IFormatProvider
和ICustomFormatter
之间的区别和联系以及它们何时被使用?一个简单的实现例子也会非常好。C#:IFormattable,IFormatProvider和ICustomFormatter之间的连接以及何时使用什么
我并不是真正意指它在.net框架中使用,但是当我自己实现这些时,那些类通常会实现什么接口以及如何正确执行它。
IFormattable
是支持格式string.Format
一个目的,即在{0:xxx}
的xxx
。如果对象支持该接口,则string.Format
将委托给对象的IFormattable.ToString
方法。
IFormatProvider
是格式化程序用于文件特定日期和货币布局等配置信息的来源。
但是,对于例如DateTime
,其中您要格式化的实例已实现IFormattable
,但您不控制实现(在BCL中提供DateTime
,您无法轻易替换它),但有一种机制可以防止string.Format
从简单地使用IFormattable.ToString
。相反,你实现了IFormatProvider
,并且当询问ICustomFormatter
实现时,返回一个。 string.Format
在委托给对象的IFormattable.Format
之前检查提供商的ICustomFormatter
,这反过来可能会要求IFormatProvider
获取特定于文化的数据,如CultureInfo
。
这里有一个程序,它显示了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")
IFormattable
是支持不同(命名/自定义)格式(例如数字等)的对象。通过使用接口,多个代码块可以使用值和格式字符串,这是很常见的(例如)在数据绑定和string.Format
。
一个IFormatProvider
填补了一些处理格式的空白 - 特别是国际化。通常使用CultureInfo
作为提供者,既可以提供特定的本地格式,也可以使用不变文化。
据我所知,ICustomFormatter
是不相关的,并且更系列化(BinaryFormatter
)。我可能是错误...
一个IFormattable
对象的示例:
IFormattable d = 123.45M;
string s1 = d.ToString("c", CultureInfo.CurrentCulture), // local currency
s2 = d.ToString("c", CultureInfo.InvariantCulture); // invariant currency
这是一个非常古老的答案,但为了孩子着想:'ICustomFormatter'确实约字符串格式化,并且不属于'增加对格式字符串的支持类型IFormattable'实现(或者为'IFormattable'对象提供不同的格式字符串)。 IFormatter是关于序列化的一个。 – 2014-01-30 21:18:09
为什么你在'MyFormatProvider.GetFormat'中返回'CultureInfo.CurrentCulture.GetFormat'?你会在'MyCustomFormatter.Format'中使用'IFormatProvider'吗? – Svish 2009-11-09 10:02:34
默认格式提供程序是CultureInfo.CurrentCulture;如果你没有在'string.Format'的重载中指定一个,那么就使用它。我已经解释了IFormatProvider的用途 - 为日期格式设置提供配置信息(例如,询问CultureInfo)(例如使用CultureInfo.DateTimeFormat)。 – 2009-11-09 11:33:17