CLR via C#

//前面那个本来想重新编辑的,但是那个编辑器之前被我调到Markdown之后,改回Tiny MCE编辑器不出来

1.ToString()方法 & IFormattable & IFormatProvider

先说ToString()

在System.Int32中定义了4个ToString方法

CLR via C#

1.无参的ToString()是重写Object的,(or ValueType)的
2,3,4用法相同,第三个可以自定义Provider

IFormattable接口

int实现了IFormattable接口

CLR via C#

IFormattable中只定义了一个ToString方法,format参数,和IFormatProvide类型的provider

IFormatProvider

在.NET中实现了IFormatProvider的类型,只有几个,其中包括SystemGlobalzation.CultureInfoIFormatProvider中定义了一个GetFormat方法(type),用来获取System.Globalization命名空间下的NumberFormatInfoDateTimeFormatInfo实例,
这两个类,同CultureInfo一样,也是IFormatProvider的实例,因为目前.NET中涉及国际化操作的,也就数字,和日期.NumberFormatInfo和DateTimeFormatInfo如果是获取关于日期,数字要格式化所需的东西.从DateTimeFormatInfo节选如下,还包括 中文,日语等等相关的内容

CLR via C#

DateTimeFormatInfo,NumberFormatInfo是IFormatProvider实例,他们的GetFormat方法,根据参数type,返回this,或者null

实例:

CLR via C#

 1 public static void Main()
 2         {
 3             int i = 999;
 4 
 5             //ToString()
 6             Console.WriteLine(i.ToString());//999
 7 
 8             //ToString(format)
 9             Console.WriteLine(i.ToString("x"));//hex 3e7
10             Console.WriteLine(i.ToString("X"));//Hex 3E7
11             Console.WriteLine(i.ToString("C"));//货币格式 ¥999.00
12 
13             //ToString(format,provider)
14             //InvariantCulture无特定文化信息,999前面那符号是 国际通用货币符号            
15             Console.WriteLine(i.ToString("C",System.Globalization.CultureInfo.InvariantCulture));//¤999.00
16             //en-US 语言-国家信息
17             Console.WriteLine(i.ToString("C",new System.Globalization.CultureInfo("en")));//$999.00
18 
19             System.Console.ReadKey();
20         }
View Code

ToString(),ToString(format)实际都等同于调用ToString(format,provider)版本,
第一个参数为空时,默认为null或者"G"(一般情况下)
第二个惨参数为空,则根据System.Globalization.CultureInfo.CurrentCulture or System.Threading.Thread.CurrentThread.CurrentCulture来获取当前调用线程的区域文化信息

2.关于String.Fornat , StringBuilder.AppendFormat

String.Format(format,param object[] arg),例如String.Format("The Post with id equals {0:x4} is wiite on {1}",1,DateTime.Now)

Format方法在碰到{0}这样的标记时,会根据冒号后面的作为format,来调用arg的ToString(format);同时Format的重载允许传递一个自定义Provider

下面结合CLR via C#上的例子,来写一个自定义IFormatProvider

功能:将char类型按unicode输出,格式
u:小写的16进制格式
U:大写的16进制格式

CLR via C#

结果显示为CLR via C#

代码为

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace CLR_String_Char
 7 {
 8     public class UnicodeFormatProvider : ICustomFormatter,IFormatProvider
 9     {
10         public object GetFormat(Type formatType)
11         {
12             if(formatType == typeof(ICustomFormatter))
13             {
14                 return this;
15             }
16             else
17             {
18                 return System.Globalization.CultureInfo.CurrentCulture.GetFormat(formatType);
19             }
20         }
21 
22         public string Format(string format,object arg,IFormatProvider formatProvider)
23         {
24             var str = string.Empty;
25             if(arg.GetType() == typeof(char) &&
26                 format != null
27               )//是char
28             {
29                 if(format=="u")
30                 {
31                     str = "\u" + ((int)((char)arg)).ToString("x4");
32                 }
33                 else if(format == "U")
34                 {
35                     str = "\u" + ((int)((char)arg)).ToString("X4");
36                 }
37             }
38             else if(arg is IFormattable)//arg 实现了IFormattable接口
39             {
40                 //formatprovider
41                 str = (arg as IFormattable).ToString(format,null);
42             }
43             else if(arg != null)
44             {
45                 str = arg.ToString();
46             }
47             return str;
48         }
49     }
50 }
View Code

在上面代码中,昨天写的,今天想想漏掉一种情况,当arg是char类型,且format不为空,format又不等于'U'和'u'的情况下,返回String.Empty是错误的,应该交给常规情况来处理

重复代码很多,可以抽象出一个基类CustomerFormatter出来

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace CLR_String_Char
 7 {
 8     public abstract class CustomFormatter<T> : ICustomFormatter,IFormatProvider
 9     {
10         //IFormatProvider.GetFormat
11         public object GetFormat(Type formatType)
12         {
13             if(formatType == typeof(ICustomFormatter))
14             {
15                 //要的就是CustomFormatter
16                 return this;
17             }
18             else
19             {
20                 return System.Globalization.CultureInfo.CurrentCulture.GetFormat(formatType);
21             }
22         }
23 
24         //ICustomFormatter.Format
25         public string Format(string format,object arg,IFormatProvider formatProvider)
26         {
27             if(arg.GetType() == typeof(T) &&
28                 format != null
29               )//是char
30             {
31                 return FormatCustom(format,(T)arg);
32             }
33             return FormatRegular(format,arg);
34         }
35 
36         //处理常规字符
37         public string FormatRegular(string format,object arg)
38         {
39             if(arg is IFormattable)//arg 实现了IFormattable接口
40             {
41                 //formatprovider
42                 return (arg as IFormattable).ToString(format,null);
43             }
44             else if(arg != null)
45             {
46                 return arg.ToString();
47             }
48             return string.Empty;
49         }
50 
51         //处理 自定义格式 类型,如果不重写,也返回FormatRegular
52         public virtual string FormatCustom(string format,T arg)
53         {
54             return FormatRegular(format,arg);
55         }
56     }
57 }

再次实现UnicodeFormatter时就简单多了,只需要继承自CustomFormatter<需要处理的类型>,再重写FormatCustom方法即可

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace CLR_String_Char
 7 {
 8     public class UnicodeFormatProvider : CustomFormatter<char>
 9     {
10         //处理所有arg is T,format不为空的情况
11         public override string FormatCustom(string format,char arg)
12         {
13             if(format == "U")
14             {
15                 return "\u"+((int)arg).ToString("X4");
16             }
17             if(format == "u")
18             {
19                 return "\u"+((int)arg).ToString("x4");
20             }
21 
22             //是char,format不为空,交给FormatRegular来处理,如果不支持,抛出FormatException
23             return base.FormatCustom(format,arg);
24         }
25     }
26 }


练练手,简单的DatetimeFormat,zh-cn格式输出咱常用的yyyy-MM-dd HH:mm:ss形式

 1     class MyDateTimeFormatter : CustomFormatter<DateTime>
 2     {
 3         public override string FormatCustom(string format,DateTime arg)
 4         {
 5             //自定义了一个格式:zh-cn
 6             if(format.Equals("zh-cn",StringComparison.OrdinalIgnoreCase))
 7             {
 8                 return arg.ToString("yyyy-MM-dd HH:mm:ss");
 9             }
10             return base.FormatCustom(format,arg);
11         }
12     }


关于Format的东西就到这里...午睡没了...啊