背景: .net的很多数据类型都提供了.Format方式,就是把数据按照一定的格式重新组织后输出。最常见的数字和日期类型:
2.5.ToString("C"); // ¥2.50
// D 10进制数
25.ToString("D5"); // 25000
// E 科学型
25000.ToString("E"); // 2.500000E+005
// F 固定点
25.ToString("F2"); // 25.00
// G 常规
2.5.ToString("G"); // 2.5
// N 数字
2500000.ToString("N"); // 2,500,000.00
// X 16进制
255.ToString("X"); // FF
// C# 日期格式
DateTime dt = DateTime.Now;
dt.ToString();//2005-11-5 13:21:25
dt.ToFileTime().ToString();//127756416859912816
dt.ToFileTimeUtc().ToString();//127756704859912816
dt.ToLocalTime().ToString();//2005-11-5 21:21:25
dt.ToLongDateString().ToString();//2005年11月5日
问题:有时会发现系统提供的方法不够用,我们需要对数据进行些特殊的处理,例如我想把日期转换成2009年11月5日星期一这种格式,系统就不支持,需要我们自己封装,当然我们非常容易实现它,但如果这种数据处理比较多呢,我们也可以写成一个工具函数来复用,但如果是多个系统都需要这种类似的处理呢?我们是不是每个系统都复制一份呢?知道C#3.0的朋友就会说了,应用扩展方法,对,这篇文章我将来谈谈如何实现自定义的formatter,而且通过扩展方法达到复用。要想实现自定义的formatter我们需要实现两个接口:IFormatProvider, ICustomFormatter。
说明:2009年11月5日星期一,这种数据格式系统有提供,大家可以看评论中园友提供的方法,这篇文章就当抛砖引玉了,同时谢谢各位园友的指点。
1):IFormatProvider:提供用于检索控制格式化的对象的机制。包含一个方法GetFormat :返回一个对象,该对象为指定类型提供格式设置服务。如果 IFormatProvider 实现能够提供该类型的对象,则为 formatType 所指定对象的实例;否则为nullNothingnullptrnull 引用
2):ICustomFormatter:定义一种方法,它支持对象值的自定义(用户定义)格式设置。包含一个方法Format:使用指定的格式和区域性特定格式设置信息将指定对象的值转换为等效的字符串表示形式。
参数说明:
1>:format 类型:String,包含格式规范的格式字符串。
2>:arg 类型:Object 要格式化的对象。
3>:formatProvider类型:IFormatProvider 一个 IFormatProvider 对象,它提供有关当前实例的格式信息。
返回值 类型:String
自定义formatter实现过程:
第一:实现自定义的formatter:MyCustomFormat,参考MSDN
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
{ return this; }
else
{
return Thread.CurrentThread.CurrentCulture.GetFormat(formatType);
}
}
public string Format(String format, object arg, IFormatProvider formatProvider)
{
String s;
IFormattable formatable = arg as IFormattable;
if (null == formatable)
{ s = arg.ToString(); }
else
{
s = formatable.ToString(format, formatProvider);
}
if (arg.GetType() == typeof(DateTime ))
{
DateTime d = (DateTime)arg ;
string dayOfWeef = d.DayOfWeek.ToString().Trim();
switch (dayOfWeef)
{
case "Monday":
dayOfWeef = "一";
break;
case "Tuesday":
dayOfWeef = "二";
break;
case "Wednesday":
dayOfWeef = "三";
break;
case "Thursday":
dayOfWeef = "四";
break;
case "Friday":
dayOfWeef = "五";
break;
case "Saturday":
dayOfWeef = "六";
break;
case "Sunday":
dayOfWeef = "日";
break;
}
return d.Year .ToString ()+"年"+d.Month .ToString ()+"月"+d.Day .ToString ()+"日"+" 星
期"+dayOfWeef ;
}
return s;
}
}
第二:把自定义的formatter扩展到DateTime的方法中。这里先要简单说明了扩展方法的应用。定义和调用扩展方法的流程:
1:定义一个静态类以包含扩展方法。 该类必须对客户端代码可见。
2:将该扩展方法实现为静态方法,并使其至少具有与包含类相同的可见性。
3:该方法的第一个参数指定方法所操作的类型;该参数必须以 this 修饰符开头。
4:在调用代码中,添加一条 using 指令以指定包含扩展方法类的命名空间。
5:按照与调用类型上的实例方法一样的方式调用扩展方法。
扩展方法详细代码如下:
{
public static string DateTimeFormat(this DateTime s)
{
string str = String.Format(new MyCustomFormat(), "{0}", s);
return str;
}
}
第三:客户端调用:可以看出代码已经简洁很多。而且其它系统复用也得到解决。
string str = "";
str = s.DateTimeFormat();