【C# IO 操作 】IFormatProvider接口|IFormattable 接口 格式化接口
IFormatProvider接口获取一个满足要求的个格式化器。
方法 object? GetFormat(Type? formatType);GetFormat方法主要提供一个满足指定要求的对象,该对象提供格式信息。GetFormat方法返回一个格式化器,通常,该格式化器的类型是一个实现了ICustomFormatter的类型对象。
IFormattable 接口 提供一种功能,用以将对象的值格式化为字符串表示形式。
方法:string ToString(string? format, IFormatProvider? formatProvider);
string? format:格式化类型例如:E、 C、N等
IFormatProvider? formatProvider: CultureInfo、DateTimeFormatInfo、NumberFormatInfo
ICustomFormatter 接口是提供给 格式化器类的。具体格式化功能在这个类的方法中实现
string Format(string? format, object? arg, IFormatProvider? formatProvider);
格式信息由谁来 Format提供 。
总结:先通过IFormatProvider接口的GetFormat()方法得到提供格式化信息的对象,再通过该对象Format()f方法的得到该对象提供的格式化信息。
IFormatProvider 接口
- 派生
IFormattable 接口
派生
案例:
public class MyFormater:ICustomFormatter,IFormatProvider { public object GetFormat(Type format) { if (format == typeof(ICustomFormatter)) return this; return null; } public string Format(string format, object arg, IFormatProvider provider) { if (format == null) { if (arg is IFormattable) return ((IFormattable)arg).ToString(format, provider); return arg.ToString(); } else { if (format == "MyFormater") { return "**" + arg.ToString(); } else { if (arg is IFormattable) return ((IFormattable)arg).ToString(format, provider); return arg.ToString(); } } } } static void Main(string[] args) { int i = 100; string printString; MyFormater myFormater = new MyFormater(); printString = string.Format(myFormater, "{0}", i); Console.WriteLine("{0}", printString); printString = string.Format(myFormater, "{0:C}", i); Console.WriteLine("{0}", printString); printString = string.Format(myFormater, "{0:MyFormater}", i); Console.WriteLine("{0}", printString); }
主要共能由string.Format 提供
public static string Format(IFormatProvider provider, string format, params object[] args) { if ((format == null) || (args == null)) { throw new ArgumentNullException((format == null) ? "format" : "args"); } StringBuilder sb = StringBuilderCache.Acquire(format.Length + (args.Length * 8)); sb.AppendFormat(provider, format, args); return StringBuilderCache.GetStringAndRelease(sb); }
结合我们的函数调用阅读函数签名,了解到:string.Format方法的第一个参数接收我们传入的自定义格式化类对象myFormater,第二个参数接收格式化字符串format,第三个参数接收需要被格式化的参数集合args,这里仅变量i。
查看string.Format方法体,可以了解到:方法先对传入参数format及args进行非法判断,参数为空时抛出参数空异常。参数正常时,初始化StringBuilder 对象(关于StringBuilderCache.Acquire的使用这里不做过多介绍,自己去研究),接着调用sb.AppendFormat方法,最后通过语句return StringBuilderCache.GetStringAndRelease(sb)返回结果。可见,真正的格式化操作都在sb.AppendFormat方法中完成,这里并不打算给出sb.AppendFormat方法的完整代码,只是给出sb.AppendFormat方法中调用GetFormat 方法和Format 方法的代码
if (provider != null) { formatter = (ICustomFormatter) provider.GetFormat(typeof(ICustomFormatter)); }
代码传入参数typeof(ICustomFormatter),返回ICustomFormatter类型的formatter 。
if (formatter != null) { if (builder != null) { str = builder.ToString(); } str2 = formatter.Format(str, arg, provider); }