如何告诉类型格式化输出的格式

分析问题

  IFormatProvider的设计思想是站在类型使用者的角度来提供格式化的方法,这和前文中介绍的IFormattable接口站在类型设计者的角度不同。IFormatProvider只包含了一个方法:object GetFormat(Type formatType)。该方法根据对象的类型给出了一个格式化器,IFormatProvider试图告诉类型用该格式化器去做格式化输出。当然最终的选择权仍然在类型设计者手中,现在在分析一下之前的代码,IFormattable.ToString方法的一开始就对IFormatProvider参数进行判断,当其不为null时,就完全采用使用者提供的格式化方法,这么做是一种信任类型用户的方式,当然,类型的设计者也可以完全不理会IFormatProvider提供的格式化器,这样做确保了类型的安全,但是却提供了非常不友好的接口。

  IFormatProvider的GetFormat方法返回一个object类型的格式化器,在通常情况下,一个实现了ICustomFormatter接口的类型对象会被返回,但这一点是无法保证的,以下代码展示了一个常用的实现IFormatProvider的方法,它在之前代码的基础上,提供了IFormatProvider的实现。

using System;

namespace Test
{
    class UseIFormatProvider:IFormattable
    {
        public DateTime _time;

        public UseIFormatProvider(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 "lsd":
                    return _time.ToShortDateString();
                case "st":
                    return _time.ToShortTimeString();
                case "G":
                case "":
                case null:
                default:
                    return _time.ToString();
            }
        }

        static void Main()
        {
            UseIFormatProvider use = new UseIFormatProvider(DateTime.Now);
            IFormatProvider provider = new MyProvider();
            Console.WriteLine(use);//调用的是IFormattable.ToString()方法
            //使用这提供格式化方法,格式化字符串不再起作用
            Console.WriteLine(use.ToString("lt", provider));
            Console.WriteLine(use.ToString("st", provider));

            Console.Read();
        }
    }

    class MyProvider : ICustomFormatter, IFormatProvider
    {
        //实现了ICustomFormatter的Format方法
        //实际的格式化工作在这里完成
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            UseIFormatProvider obj = arg as UseIFormatProvider;
            if (obj==null)
            {
                return arg.ToString();
            }
            return obj._time.ToString("yyyy-MM-dd hh:mm:ss");
        }

        //本类型可以实现对UseIFormatProvider类型的格式化
        public object GetFormat(Type formatType)
        {
            if (formatType==typeof(UseIFormatProvider))
            {
                return this;
            }
            else
            {
                return null;
            }
        }
    }

}

  如以上代码所示,MyProvider的GetFormat方法返回了一个实现了ICustomFormat接口的类型对象,这在以上代码中就是MyProvider的对象本身,并且在Format方法中实现了具体的格式化方法。

  在通常情况下,由类型使用者来实现格式化并不容易,因为他不能随心所欲地访问类型的内部成员。而类型的设计者实现格式化输出时,又势必很难覆盖所有类型使用这的需求,这就需要两者进行有效的协调。就如以上代码所展示的那样,类型设计者实现了一部分常用的格式化需求,并且允许使用者提供他们自己的格式化方法。

答案

  IFormatProvider让类型的使用者有机会提供格式化的方法。GetFormat方法返回一个格式化器,在通常情况下,该格式化器的类型是一个实现了ICustomFormatter的类型对象。IFormatProvider接口和IFormattable接口一起可以实现灵活强大的格式化输出。

如何告诉类型格式化输出的格式

时间: 2024-11-29 07:16:17

如何告诉类型格式化输出的格式的相关文章

变量/常量/格式化输出/运算

一. 变量: 解释:将程序运算的中间结果这哪是存储起来,以便后续程序调用. 1,  变量必须要有数字,字母,下划线,任意组合. 2, 变量不能数字开头. 3, 不能是python中的关键字. ['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import',

python基础知识梳理----2格式化输出,替换符

一:格式化输出 1: 格式: 例子: name=input('请输入name') print('名字是%s'%name) %s就是代表字符串串占位符,除此之外,还有%d, 是数字占位符, 如果把上?面的age后?面的换成%d,就代表你必须只 能输入数字啦 这时对应的数据必须是int类型. 否则程序会报错 用了这么久几乎都是%s  因为这个是万能匹配 2: 强制转换 字符型转数字型    int() 例子  int('123') 输出 123  #### 数字型 强制转换  数字型转字符型   s

go语言基础之格式化输出

1.fmt包的格式化输出输入 格式说明 格式 含义 %% 一个%字面量 %b 一个二进制整数值(基数为2),或者是一个(高级的)用科学计数法表示的指数为2的浮点数 %c 字符型.可以把输入的数字按照ASCII码相应转换为对应的字符 %d 一个十进制数值(基数为10) %e 以科学记数法e表示的浮点数或者复数值 %E 以科学记数法E表示的浮点数或者复数值 %f 以标准记数法表示的浮点数或者复数值 %g 以%e或者%f表示的浮点数或者复数,任何一个都以最为紧凑的方式输出 %G 以%E或者%f表示的浮

[转].tostring设置格式。C# tostring 格式化输出

http://blog.csdn.net/hyynet09/article/details/4219488 C 货币 2.5.ToString("C") ¥2.50 D 十进制数 25.ToString("D5") 00025 E 科学型 25000.ToString("E") 2.500000E+005 F 固定点 25.ToString("F2") 25.00 G 常规 2.5.ToString("G"

字符格式化输出,类型强制转换,点访问数据属性,

name = input("Name:") age = int(input("Age:"))       #类型强制转换 job = input("Job:") salary = input("Salary:") if salary.isdigit():                 #  .isdigit()用于判断数据是不是数字 salary = int(salary) msg = ''' ----------info

7.31(三种格式化输出的方式,基本运算类型,if循环)

复习 数据类型基础 变量是用来描述世间万物变化状态的,但是万物的状态是有多种的,要用不同的数据类型来表示 五大数据类型(数字类型,字符串,列表,字典,布尔类型) 数字类型又包括整型和浮点型 定义方式:age = 18:age = int(18):int('18') age = 18,age1 = 19 print(age,age1) age,age1 = 18.19 作用:描述年龄/id号等 使用方法:+-*/%//** 如果使用log方法,导入import cmath库 浮点型 定义方式:sa

java基础---->Java的格式化输出

在JavaSe5中,推出了C语言中printf()风格的格式化输出.这不仅使得控制输出的代码更加简单,同时也给与Java开发者对于输出格式与排列更大的控制能力.今天,我们开始学习Java中的格式化输出. 目录导航 System.out.format() Formatter类 格式化说明符 Formatter转换 简单的十六进制转换工具 友情链接 System.out.format() 由于内容比较简单,我们通过实例来加以说明.项目结构如下: Java Se5引入的format方法可用于Print

如何使用IFormattable接口实现格式化输出

分析问题 在设计类型时,程序员应该尽量为类型使用者着想,其中重要的一点就是提供格式化的字符串输出.为类型编写格式化输出接口,类型自身和其使用者都将得到收益.对于一些类型,重写基类中的ToString方法就已经足够了,但对于有些类型,则需要提供多种格式的输出,这个时候ToString方法就不能满足需求了.此时就需要实现IFormattable中的ToString方法: String IFormattable.ToString(String format,IFormatProvider format

Python 格式化输出

2017-07-29  22:03:07 一.使用格式符%进行格式控制 %[(name)][flags][width].[precision]typecode (name):命名 flags:可以有+,-,' '或0.+表示右对齐.-表示左对齐.' '为一个空格,表示在正数的左侧填充一个空格,从而与负数对齐.0表示使用0填充 wideth : 表示显示宽度,占位个数 precision : 表示小数点后精度 typecode : 格式符为真实值预留位置,并控制显示的格式.格式符可以包含有一个类型