1. ToString() 格式化入门为什么我们需要它刚接触C#的时候我经常被各种数字显示问题困扰。比如在开发一个电商系统时商品价格直接显示19.9显得很业余而19.90就专业多了在做数据分析时1500000和1,500,000的阅读体验天差地别。这就是ToString()格式化的用武之地。上周我帮朋友调试一个财务软件他抱怨报表数字乱七八糟。原来他直接用ToString()输出浮点数导致金额显示忽长忽短。我教他用ToString(N2)固定两位小数后他惊呼早该学这个其实这些技巧就在ToString()的参数里只是很多人没系统了解过。基础格式化分为标准格式字符串和自定义格式字符串两种。标准格式字符串是单个字母比如double price 19.9; Console.WriteLine(price.ToString(C)); // 输出19.90而自定义格式字符串可以更灵活Console.WriteLine(price.ToString(0.00)); // 同样输出19.902. 标准格式说明符实战财务系统的救星2.1 货币格式化C在开发财务系统时货币格式化使用频率最高。最近我给某超市做的收银系统就大量用到了C格式符。有趣的是不同地区的输出会自动适配123.45.ToString(C, new CultureInfo(en-US)); // $123.45 123.45.ToString(C, new CultureInfo(zh-CN)); // 123.45精度控制也很简单// 超市价签常用一位小数 19.9.ToString(C1); // 19.9 // 财务报表需要精确到分 19.9.ToString(C2); // 19.902.2 数字格式化N做数据可视化时大数字加千位分隔符能提升可读性。去年我做疫情数据展示时就深有体会1500000.ToString(N0); // 1,500,000 1500000.ToString(N); // 1,500,000.00注意N0和N的区别N0不要小数部分N默认两位小数。在展示人口数量时用N0展示精确数据时用N。2.3 百分比格式化P做KPI仪表盘时百分比格式化特别实用。我见过有人手动乘100加%号其实用P格式符更优雅0.154.ToString(P0); // 15% 0.154.ToString(P1); // 15.4% 0.154.ToString(P2); // 15.40%第二个参数控制小数位数这在显示转化率时特别有用。3. 自定义格式模式打造专属显示方案3.1 占位符0和#的区别很多新手分不清0和#我在教实习生时常用这个例子12.3.ToString(000.000); // 012.300 12.3.ToString(###.###); // 12.30是强制占位符空缺补零#是可选占位符空缺省略。在做工号生成时我用过这个特性// 生成6位工号不足补零 123.ToString(000000); // 0001233.2 小数点与千分位做国际项目时要注意小数点符号的本地化问题。去年我们系统在德国上线时就出过bug// 德国用逗号表示小数点 1234.56.ToString(N2, new CultureInfo(de-DE)); // 1.234,56自定义格式时可以用.表示小数点,表示千分位1234567.ToString(#,##0.00); // 1,234,567.003.3 文本与转义在生成订单编号时我经常混入固定文本DateTime.Now.ToString(订单号yyyyMMddHHmmss); // 输出订单号20230815143025单引号内的内容会原样输出这个技巧在生成报表标题时也很实用。4. 综合实战财务报表生成器去年我开发过一个财务报表系统就用到了各种格式化技巧。比如利润表需要// 金额列千分位两位小数右对齐 string.Format({0,12:N2}, 1500000); // 1,500,000.00 // 增长率列百分比红色显示负值 var growth -0.125; string.Format(growth 0 ? \x1b[31m{0:P1}\x1b[0m : {0:P1}, growth); // 输出红色-12.5%资产负债表更复杂需要处理多种格式// 资产总计行 var assets 1234567890; Console.WriteLine(${资产总计,-10}{assets.ToString(C0),15}); // 输出资产总计 1,234,567,8905. 性能优化与常见陷阱5.1 避免重复格式化在循环中频繁调用ToString()会影响性能。我优化过一个导出百万行数据的系统// 错误做法每次循环都格式化 foreach(var item in hugeList) { csv.AppendLine(item.Value.ToString(N2)); } // 正确做法提前设置格式 var format N2; foreach(var item in hugeList) { csv.AppendLine(item.Value.ToString(format)); }5.2 文化差异陷阱做跨境电商系统时我踩过货币符号的坑// 美国用户看到的是美元符号 12.5.ToString(C, new CultureInfo(en-US)); // $12.50 // 中国用户看到的是人民币符号 12.5.ToString(C, new CultureInfo(zh-CN)); // 12.50解决方案是统一指定文化信息或者使用中性符号12.5.ToString(¤0.00, CultureInfo.InvariantCulture); // ¤12.505.3 自定义格式的边界情况处理用户输入时要特别注意极端值// 超大数会破坏格式 1234567890123456789.ToString(###,###); // 1,234,567,890,123,456,789 // 科学计数法可能更合适 1234567890123456789.ToString(0.###E0); // 1.235E18这些经验都是我在实际项目中踩坑后总结的。格式化看似简单但要用好需要不断实践。建议你在自己的项目中多尝试不同的格式组合遇到特殊需求时查阅官方文档里面有很多隐藏技巧。