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 in string.Format
, i.e. the xxx
in {0:xxx}
. string.Format
will delegate to an object's IFormattable.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 implements IFormattable
yet you don't control the implementation (DateTime
is supplied in the BCL, you can't replace it easily), there is a mechanism to prevent string.Format
from simply using IFormattable.ToString
. Instead, you implement IFormatProvider
, and when asked for an ICustomFormatter
implementation, return one. string.Format
checks the provider for an ICustomFormatter
before it delegates to the object's IFormattable.Format
, which would in turn likely ask the IFormatProvider
for culture-specific data like CultureInfo
.
这是一个程序,它显示了 string.Format
向 IFormatProvider
请求什么,以及控制流程是如何进行的:
Here is a program which shows what string.Format
asks the IFormatProvider
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 之间的连接,以及何时使用什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!