问题描述
IFormattable
、IFormatProvider
和ICustomFormatter
有什么区别和联系,什么时候用?一个简单的实现示例也会非常好.
What are the difference and connection between IFormattable
, IFormatProvider
and ICustomFormatter
and when would they be used? A simple implementation example would be very nice too.
我并不是说什么时候在 .net 框架中使用它,而是什么时候我自己实现这些,在这种情况下,什么类通常会实现什么接口以及如何正确地实现它.
And I don't really mean when it is used in the .net framework, but when I would implement these myself and in that case what classes would typically implement what interface and how to do it properly.
推荐答案
IFormattable
是一个支持string.Format
格式的对象,即{0:xxx中的
xxx
}代码>.如果对象支持接口,string.Format
将委托给对象的IFormattable.ToString
方法.IFormattable
is an object which supports formats instring.Format
, i.e. thexxx
in{0:xxx}
.string.Format
will delegate to an object'sIFormattable.ToString
method if the object supports the interface.IFormatProvider
是格式化程序用于特定文化的日期和货币布局等配置信息的来源.IFormatProvider
is a source of configuration information that formatters use for things like culture-specific date and currency layout.但是,对于例如
DateTime
,您要格式化的实例已经实现IFormattable
但您不控制实现(DateTime
在 BCL 中提供,您不能轻易替换),有一种机制可以防止string.Format
简单地使用IFormattable.ToString
.相反,您实现IFormatProvider
,当被要求提供ICustomFormatter
实现时,返回一个.string.Format
在委托给对象的IFormattable.Format
之前检查提供程序的ICustomFormatter
,这反过来可能会询问IFormatProvider
用于特定于文化的数据,例如CultureInfo
.However, for situations like e.g.
DateTime
, where the instance you want to format already implementsIFormattable
yet you don't control the implementation (DateTime
is supplied in the BCL, you can't replace it easily), there is a mechanism to preventstring.Format
from simply usingIFormattable.ToString
. Instead, you implementIFormatProvider
, and when asked for anICustomFormatter
implementation, return one.string.Format
checks the provider for anICustomFormatter
before it delegates to the object'sIFormattable.Format
, which would in turn likely ask theIFormatProvider
for culture-specific data likeCultureInfo
.这是一个程序,它显示了
string.Format
向IFormatProvider
请求什么,以及控制流程是如何进行的:Here is a program which shows what
string.Format
asks theIFormatProvider
for, and how the flow of control goes: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
如果格式提供程序更改为返回自定义格式化程序,它将接管:
If the format provider is changed to return a custom formatter, it takes over:
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")
这篇关于C#:IFormattable、IFormatProvider 和 ICustomFormatter 之间的连接,以及何时使用什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!