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)\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的使用
学习技术最好的文档就是【官方文档】,没有之一。
还有学习资料【Microsoft Learn】、【CSharp Learn】、【My Note】。
如果,你认为阅读这篇博客让你有些收获,不妨点击一下右下角的【推荐】按钮。
如果,你希望更容易地发现我的新博客,不妨点击一下【关注】。