您的位置:首页 > 其它

如何告诉类型格式化输出的格式

2014-08-19 16:54 169 查看
分析问题

  IFormatProvider的设计思想是站在类型使用者的角度来提供格式化的方法,这和前文中介绍的IFormattable接口站在类型设计者的角度不同。IFormatProvider只包含了一个方法:object GetFormat(Type formatType)。该方法根据对象的类型给出了一个格式化器,IFormatProvider试图告诉类型用该格式化器去做格式化输出。当然最终的选择权仍然在类型设计者手中,现在在分析一下之前的代码,IFormattable.ToString方法的一开始就对IFormatProvider参数进行判断,当其不为null时,就完全采用使用者提供的格式化方法,这么做是一种信任类型用户的方式,当然,类型的设计者也可以完全不理会IFormatProvider提供的格式化器,这样做确保了类型的安全,但是却提供了非常不友好的接口。

  IFormatProvider的GetFormat方法返回一个object类型的格式化器,在通常情况下,一个实现了ICustomFormatter接口的类型对象会被返回,但这一点是无法保证的,以下代码展示了一个常用的实现IFormatProvider的方法,它在之前代码的基础上,提供了IFormatProvider的实现。

using System;

namespace Test
{
class UseIFormatProvider:IFormattable
{
public DateTime _time;

public UseIFormatProvider(DateTime time)
{
_time = time;
}
//重写ToString方法
public override string ToString()
{
return "Object.ToString()";
}

public string ToString(string format, IFormatProvider formatProvider)
{
//这里判断使用者是否提供了格式化器
if (formatProvider!=null)
{
ICustomFormatter fmt = formatProvider.GetFormat(this.GetType()) as ICustomFormatter;
if (fmt!=null)
{
return fmt.Format(format, this, formatProvider);
}
}
//这里实现格式化输出
switch (format)
{
case "ld":
return _time.ToLongDateString();
case "lt":
return _time.ToLongTimeString();
case "lsd":
return _time.ToShortDateString();
case "st":
return _time.ToShortTimeString();
case "G":
case "":
case null:
default:
return _time.ToString();
}
}

static void Main()
{
UseIFormatProvider use = new UseIFormatProvider(DateTime.Now);
IFormatProvider provider = new MyProvider();
Console.WriteLine(use);//调用的是IFormattable.ToString()方法
//使用这提供格式化方法,格式化字符串不再起作用
Console.WriteLine(use.ToString("lt", provider));
Console.WriteLine(use.ToString("st", provider));

Console.Read();
}
}

class MyProvider : ICustomFormatter, IFormatProvider
{
//实现了ICustomFormatter的Format方法
//实际的格式化工作在这里完成
public string Format(string format, object arg, IFormatProvider formatProvider)
{
UseIFormatProvider obj = arg as UseIFormatProvider;
if (obj==null)
{
return arg.ToString();
}
return obj._time.ToString("yyyy-MM-dd hh:mm:ss");
}

//本类型可以实现对UseIFormatProvider类型的格式化
public object GetFormat(Type formatType)
{
if (formatType==typeof(UseIFormatProvider))
{
return this;
}
else
{
return null;
}
}
}

}


  如以上代码所示,MyProvider的GetFormat方法返回了一个实现了ICustomFormat接口的类型对象,这在以上代码中就是MyProvider的对象本身,并且在Format方法中实现了具体的格式化方法。

  在通常情况下,由类型使用者来实现格式化并不容易,因为他不能随心所欲地访问类型的内部成员。而类型的设计者实现格式化输出时,又势必很难覆盖所有类型使用这的需求,这就需要两者进行有效的协调。就如以上代码所展示的那样,类型设计者实现了一部分常用的格式化需求,并且允许使用者提供他们自己的格式化方法。

答案

  IFormatProvider让类型的使用者有机会提供格式化的方法。GetFormat方法返回一个格式化器,在通常情况下,该格式化器的类型是一个实现了ICustomFormatter的类型对象。IFormatProvider接口和IFormattable接口一起可以实现灵活强大的格式化输出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐