• IFormattable和IFormatProvider


    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)
    ", 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)
    ", temp1));
    

    示例代码

    UseIFormattable
    UseIFormatProvider

    参考资料

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

  • 相关阅读:
    Codeforces Round #595 (Div. 3) A,B,C,D
    计算几何板子题【2019牛客国庆集训派对day7——三角形和矩形】【多边形相交的面积】
    [POJ]POJ1753(dfs)
    [POJ]POJ2965(dfs)
    洛谷 P1772 [ZJOI2006]物流运输 题解
    简单概率与期望
    洛谷 P3802 小魔女帕琪 题解
    用树状数组实现的平衡树
    【模板】扩展中国剩余定理(EXCRT)
    新博客开通通知
  • 原文地址:https://www.cnblogs.com/Lulus/p/12519829.html
Copyright © 2020-2023  润新知