我不会称之为漂亮,但它属于“它有效”的类别。
首先是实现,
public static class FormatProviderExtensions
{
public static IFormatProvider GetCustomFormatter(this NumberFormatInfo info, decimal d)
{
var truncated = Decimal.Truncate(d);
if (truncated == d)
{
return new NumberFormatInfo
{
NumberDecimalDigits = 0,
NumberDecimalSeparator = info.NumberDecimalSeparator,
NumberGroupSeparator = info.NumberGroupSeparator
};
}
// The 4th element contains the exponent of 10 used by decimal's
// representation - for more information see
// https://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx
var fractionalDigitsCount = BitConverter.GetBytes(Decimal.GetBits(d)[3])[2];
return fractionalDigitsCount <= 2
? new NumberFormatInfo
{
NumberDecimalDigits = 2,
NumberDecimalSeparator = info.NumberDecimalSeparator,
NumberGroupSeparator = info.NumberGroupSeparator
}
: new NumberFormatInfo
{
NumberDecimalDigits = fractionalDigitsCount,
NumberDecimalSeparator = info.NumberDecimalSeparator,
NumberGroupSeparator = info.NumberGroupSeparator
};
}
}
和示例用法:
var d = new[] { 500000m, 500000.9m, 500000.99m, 500000.999m, 500000.9999m };
var info = new NumberFormatInfo { NumberDecimalSeparator = ",", NumberGroupSeparator = "" };
d.ToList().ForEach(x =>
{
Console.WriteLine(String.Format(info.GetCustomFormatter(x), "{0:N}", x));
});
输出:
500000
500000,90
500000,99
500000,999
500000,9999
它从现有的NumberFormatInfo 中获取我们关心的属性,并返回一个带有我们想要的NumberDecimalDigits 的新属性。它在丑陋的规模上相当高,但使用起来很简单。