分析问题
在设计类型时,程序员应该尽量为类型使用者着想,其中重要的一点就是提供格式化的字符串输出。为类型编写格式化输出接口,类型自身和其使用者都将得到收益。对于一些类型,重写基类中的ToString方法就已经足够了,但对于有些类型,则需要提供多种格式的输出,这个时候ToString方法就不能满足需求了。此时就需要实现IFormattable中的ToString方法:
String IFormattable.ToString(String format,IFormatProvider formatProvider)
该方法接受两个参数,第一个字符串参数告诉方法需要何种格式的输出,而第二个IFormatProvider的参数则允许类型使用者自定义格式化方法。IFormatProvider接口将在后续小节中讨论。以下代码展示了如何实现IFormattable接口。
using System; namespace Test { class UseIFormattable:IFormattable { private DateTime _time; public UseIFormattable(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 "sd": return _time.ToShortDateString(); case "st": return _time.ToShortTimeString(); case "G": //null和""在这里实现 default: return _time.ToString(); } } static void Main() { UseIFormattable use = new UseIFormattable(DateTime.Now); //调用IFormattable.ToString方法 Console.WriteLine(use); Console.WriteLine(use.ToString("ld", null)); Console.WriteLine(use.ToString("lt", null)); Console.WriteLine(use.ToString("sd", null)); Console.WriteLine(use.ToString("st", null)); Console.Read(); } } }
如上面代码所示,IFormattable.ToString方法主要使用第一个字符串参数来作为输出的依据,根据不同的输入来格式化类型对象。在实现IFormattable接口时,有几点需要读者注意:
1、实现IFormattable.ToString方法通常可以自定义接受的格式字符串,但有三个字符串应该被实现:“G”、null和Empty。不实现这三个格式不会造成编译或者运行的错误,但潜在地违反了.NET的内建规范。
2、当实现了IFormattable.ToString方法后,所有的内建类型都将调用IFormattable.ToString方法,而不是继承自System.Object的ToString方法。在以上代码中,Console.WriteLine方法就是一个例子。
3、内建方法会自动调用IFormattable.ToString方法,使用的参数可能是“G”,也可能是空字符串,建议读者在设计类型时,把这几个格式实现成和Object.ToString具有相同的输出。
4、在IFormattable.ToString方法的一开始,对IFormatProvider参数进行了检查,这一机制将在后续小节中详细介绍,简单来讲,它实现了让类型使用者提供格式化方法的功能。
以下是上边代码的输出:
答案
IFormattable接口帮助类型实现了多样化的格式化输出。IFormattable的ToString方法接受一个代表格式的字符串参数,通过对这个参数的分析来进行格式化输出。另外,IFormattable.ToString方法接受一个IFormatProvider类型的参数,以允许类型的使用者提供格式化的方法。
如何使用IFormattable接口实现格式化输出