如何将可空decimal类型格式化为保留两位小数的字符串?
解决可空decimal格式化保留两位小数的问题
这个坑我之前踩过!确实,decimal?(也就是Nullable<decimal>)类型的ToString方法没有带格式字符串参数的重载,所以直接对Sum()的结果调用.ToString("#.##")会触发你看到的错误。下面给你几种靠谱的解决办法:
方法1:先处理null,再格式化
通过HasValue判断是否有值,或者用null合并运算符??给出默认值,再调用带格式的ToString:
情况A:总和为null时显示默认值(比如"0.00")
Salary = g.Where(x => !String.IsNullOrEmpty(x.Salary)) .Select(x => (decimal?)decimal.Parse(x.Salary)) .DefaultIfEmpty(null) .Sum() ?.ToString("#.##") ?? "0.00";
这里?.会在总和为null时跳过ToString直接返回null,然后??把null替换成"0.00",你也可以改成其他符合需求的默认值。
情况B:总和为null时显示空字符串
var totalSalary = g.Where(x => !String.IsNullOrEmpty(x.Salary)) .Select(x => (decimal?)decimal.Parse(x.Salary)) .DefaultIfEmpty(null) .Sum(); Salary = totalSalary.HasValue ? totalSalary.Value.ToString("#.##") : string.Empty;
先把总和存到变量里,再判断是否有值:有值就取Value(原生decimal类型)调用带格式的ToString,没值就返回空字符串。
方法2:用string.Format或插值字符串处理
string.Format和C# 6+的插值字符串可以自动处理可空类型,内部会帮你判断是否有值并拆箱:
使用string.Format
Salary = string.Format("{0:#.##}", g.Where(x => !String.IsNullOrEmpty(x.Salary)) .Select(x => (decimal?)decimal.Parse(x.Salary)) .DefaultIfEmpty(null) .Sum());
如果总和为null,string.Format会返回空字符串;要是想让null时显示"0.00",可以把格式改成"{0:#.##;0.00}"。
使用插值字符串(更简洁)
var totalSalary = g.Where(x => !String.IsNullOrEmpty(x.Salary)) .Select(x => (decimal?)decimal.Parse(x.Salary)) .DefaultIfEmpty(null) .Sum(); Salary = $"{totalSalary:#.##}";
写法更直观,效果和string.Format完全一致。
补充小提示
- 不管用哪种方法,
#.##格式都会自动把超长的decimal四舍五入到两位小数,比如你提到的203827.82763651324038269会变成203827.83,完全符合你的需求。 - 如果你的数据源里
Salary可能存在非数字的情况,建议把decimal.Parse换成decimal.TryParse来避免抛出异常,比如:x => decimal.TryParse(x.Salary, out var sal) ? (decimal?)sal : null,这样代码会更健壮。
内容的提问来源于stack exchange,提问作者webworm
相关产品推荐
相关产品推荐

