首页 > 其他 > 详细

IFormattable和IFormatProvider

时间:2020-03-18 20:37:37      阅读:46      评论:0      收藏:0      [点我收藏+]

IFormattable和IFormatProvider用于格式化输出,比如日期格式(2020/3/18 19:56:29、2020年3月18日)、数字格式(小数位、数值类型decimal/float/double)、其他需要规范输出的应用场景。
IFormattable 接口将对象的值格式化为字符串表示形式。
IFormatProvider 接口检索对象以控制格式化。

IFormattable 接口的示例为例,根据摄氏度,格式化输出对应华氏度和开尔文。
格式化类型包括G(默认,摄氏度)、C(摄氏度)、F(华氏度)、K(开尔文)。

单独使用IFormattable

IFormattable 的ToString方法接受一个代表格式的字符串参数,通过对这个参数的分析来进行格式化输出。
需要格式化的类直接实现IFormattable 接口,Temperature(温度)类直接实现IFormattable接口。

public class Temperature : IFormattable
{
    private decimal temp;

    public Temperature(decimal temperature)
    {
        if (temperature < -273.15m)
            throw new ArgumentOutOfRangeException(String.Format("{0}低于绝对零度",temperature));
        this.temp = temperature;
    }

    /// <summary>
    /// 摄氏度
    /// </summary>
    public decimal Celsius
    {
        get { return temp; }
    }

    /// <summary>
    /// 华氏温度
    /// </summary>
    public decimal Fahrenheit
    {
        get { return temp * 9 / 5 + 32; }
    }

    /// <summary>
    /// 开尔文(热力学温标或称绝对温标)
    /// </summary>
    public decimal Kelvin
    {
        get { return temp + 273.15m; }
    }

    public override string ToString()
    {
        return this.ToString("G", CultureInfo.CurrentCulture);
    }

    public string ToString(string format)
    {
        return this.ToString(format, CultureInfo.CurrentCulture);
    }

    public string ToString(string format, IFormatProvider provider)
    {
        if (String.IsNullOrEmpty(format)) format = "G";
        if (provider == null) provider = CultureInfo.CurrentCulture;
                
                //G(默认,摄氏度)、C(摄氏度)、F(华氏度)、K(开尔文)
        switch (format.ToUpperInvariant())
        {
            case "G":
            case "C":
                return temp.ToString("F2", provider) + " °C";
            case "F":
                return Fahrenheit.ToString("F2", provider) + " °F";
            case "K":
                return Kelvin.ToString("F2", provider) + " K";
            default:
                throw new FormatException(String.Format("{0}格式不被支持", format));
        }
    }
}
Temperature temp1 = new Temperature(0);
//带有格式化字符串C/K/F
Console.WriteLine("{0:C} (Celsius) = {0:K} (Kelvin) = {0:F} (Fahrenheit)\n", temp1);
//其他写法见示例代码

使用IFormatProvider

String.Format方法接受一个IFormatProvider类型的参数,以允许类型的使用者提供格式化的方法。

public class Temperature
{
    internal decimal temp;

    public Temperature(decimal temperature)
    {
        if (temperature < -273.15m)
            throw new ArgumentOutOfRangeException(String.Format("{0}低于绝对零度.",temperature));
        this.temp = temperature;
    }
}

单独写自定义FormatProvider类实现格式化输出,并在格式化方法中加入这个FormatProvider类对象。

public class TemperatureFormatProvider : IFormatProvider, ICustomFormatter
{
    public string Format(string format, object arg, IFormatProvider provider)
    {
        if (arg.GetType() != typeof(Temperature))
            throw new FormatException(String.Format("类型 '{0}' 是无效的.", arg.GetType().ToString()));

        decimal temp = (arg as Temperature).temp;

        if (String.IsNullOrEmpty(format)) format = "G";
        if (provider == null) provider = CultureInfo.CurrentCulture;

        switch (format.ToUpperInvariant())
        {
            case "G":
            case "C":
                return temp.ToString("F2", provider) + " °C";
            case "F":
                var Fahrenheit= temp * 9 / 5 + 32;
                return Fahrenheit.ToString("F2", provider) + " °F";
            case "K":
                var Kelvin= temp + 273.15m;
                return Kelvin.ToString("F2", provider) + " K";
            default:
                throw new FormatException(String.Format("{0}格式不被支持.", format));
        }
    }

    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(ICustomFormatter))
            return this;
        else
            return null;
    }
}
Console.WriteLine(String.Format(new TemperatureFormatProvider(), "{0:C} (Celsius) = {0:K} (Kelvin) = {0:F} (Fahrenheit)\n", temp1));

示例代码

UseIFormattable
UseIFormatProvider

参考资料

IFormattable 接口
IFormatProvider 接口
.NET基础 (13)IFormattable和IformatProvider的使用

IFormattable和IFormatProvider

原文:https://www.cnblogs.com/Lulus/p/12519829.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!