关闭

建议13: 为类型输出格式化字符串(1)

标签: IFormattableIFormatProvider
130人阅读 评论(0) 收藏 举报
分类:

建议13: 为类型输出格式化字符串(1)

有两种方法可以为类型提供格式化的字符串输出。一种是意识到类型会产生格式化字符串输出,于是让类型继承接口IFormattable。这对类型来说,是一种主动实现的方式,要求开发者可以预见类型在格式化方面的要求。更多的时候,类型的使用者需为类型自定义格式化器,这就是第二种方法,也是最灵活多变的方法,可以根据需求的变化为类型提供多个格式化器。下面就来详细介绍这两种方法。

最简单的字符串输出是为类型重写ToString方法,如果没有为类型重写该方法,默认会调用Object的ToString方法,它会返回当前类型的类型名称。但即使是重写了ToString方法,提供的字符串输出也是非常单一的,而通过实现IFormattable接口的ToString方法,可以让类型根据用户的输入而格式化输出。如下面这个类型Person,它本身提供了属性FirstName和LastName。现在,根据中文和英文语言地区的习惯,提供的ToString方法要支持输出“Hu Jessica”或 “Jessica Hu”,实现代码应该如下所示:

  1. class Person : IFormattable  
  2. {  
  3.     public string IDCode { get; set; }  
  4.     public string FirstName { get; set; }  
  5.     public string LastName { get; set; }  
  6.  
  7.     //实现接口IFormattable的方法ToString  
  8.     public string ToString(string format, IFormatProvider formatProvider)  
  9.     {  
  10.         switch (format)  
  11.         {  
  12.             case "Ch":  
  13.                 return this.ToString();  
  14.             case "Eg":  
  15.                 return string.Format("{0} {1}", FirstName, LastName);  
  16.             default:  
  17.                 return this.ToString();  
  18.         }  
  19.     }  
  20.  
  21.     //重写Object.ToString()  
  22.     public override string ToString()  
  23.     {  
  24.         return string.Format("{0} {1}", LastName, FirstName);  
  25.     }  

调用者代码如下所示:

  1. Person person = new Person() { FirstName = "Jessica"LastName = "Hu",  
  2.     IDCode = "NB123" };  
  3. Console.WriteLine(person);  
  4. Console.WriteLine(person.ToString("Ch", null));  
  5. Console.WriteLine(person.ToString("Eg", null)); 

输出为:
  1. Hu Jessica  
  2. Hu Jessica  
  3. Jessica Hu 

上面这种方法是在意识到类型会存在格式化字符串输出方面的需求时,提前为类型继承了接口IFormattable。如果类型本身没有提供格式化输出的功能,这个时候,格式化器就派上了用场。格式化器的好处就是可以根据需求的变化,随时增加或者修改它。假设Person类如以下所示的实现。
  1. class Person  
  2. {  
  3.     public string IDCode { get; set; }  
  4.     public string FirstName { get; set; }  
  5.     public string LastName { get; set; }  

针对Person的格式化器的实现为:
  1. class PersonFomatter : IFormatProvider, ICustomFormatter  
  2. {  
  3.  
  4.     #region IFormatProvider 成员  
  5.  
  6.     public object GetFormat(Type formatType)  
  7.     {  
  8.         if (formatType == typeof(ICustomFormatter))  
  9.             return this;  
  10.         else  
  11.             return null;  
  12.     }  
  13.  
  14.     #endregion  
  15.  
  16.     #region ICustomFormatter 成员  
  17.  
  18.     public string Format(string format, object arg,  
  19.         IFormatProvider formatProvider)  
  20.     {  
  21.         Person person = arg as Person;  
  22.         if (person == null)  
  23.         {  
  24.             return string.Empty;  
  25.         }  
  26.  
  27.         switch (format)  
  28.         {  
  29.             case "Ch":  
  30.                 return string.Format("{0} {1}", person.LastName,  
  31.                     person.FirstName);  
  32.             case "Eg":  
  33.                 return string.Format("{0} {1}", person.FirstName,  
  34.                     person.LastName);  
  35.             case "ChM":  
  36.                 return string.Format("{0} {1} : {2}", person.LastName,  
  37.                     person.FirstName, person.IDCode);  
  38.             default:  
  39.                 return string.Format("{0} {1}", person.FirstName,  
  40.                     person.LastName);  
  41.         }  
  42.     }  
  43.  
  44.     #endregion  

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:34769次
    • 积分:671
    • 等级:
    • 排名:千里之外
    • 原创:9篇
    • 转载:157篇
    • 译文:0篇
    • 评论:0条
    文章分类