C#点餐程序中已格式化货币字符串的数值相加问题求助
C#点餐程序货币数值相加问题解决方法
问题描述
开发C#点餐程序时遇到一个实际问题:用户选择标价£5的披萨后,添加80p的额外芝士,本应合计£5.80,但由于价格被自动格式化为货币字符串,无法进行数值解析与计算,最终出现£5.00£0.80的字符串拼接结果,而非正确的数值相加。
核心原因
问题的本质是把用于展示的货币字符串当成了计算用的数据类型:如果Pizza、Topping等类的Price属性被定义为string,那么代码中的+=操作就会变成字符串拼接,而非数值相加。货币计算必须使用精确的数值类型,格式化仅用于最终展示环节。
解决方案
1. 统一修改Price属性为decimal类型
所有涉及价格的实体类(Pizza、Burger、Topping、Garnish),将Price属性改为decimal类型(优先用decimal,避免float/double的精度丢失问题):
// Pizza类示例 public class Pizza : FoodItems { public decimal Price { get; set; } // 其他属性与方法... } // Topping类示例 public class Topping { public string Name { get; set; } public decimal Price { get; set; } }
2. 重写ToString方法实现货币格式化
在实体类中重写ToString,仅在需要展示时格式化为英镑货币字符串:
public class Pizza : FoodItems { public decimal Price { get; set; } // 其他属性... public override string ToString() { // 格式化为带英镑符号的两位小数字符串 return $"{Name} - £{Price:F2}"; } } public class Topping { public string Name { get; set; } public decimal Price { get; set; } public override string ToString() { return $"{Name} - £{Price:F2}"; } }
3. 修正代码中的数值相加逻辑
现在添加配料时的价格相加会自动执行数值计算:
// 添加配料的代码片段修正 Topping toppingToAdd = _topping.ElementAt(toppingIndex - currentToppings.Count); if (selectedItem is Pizza pizza1) { pizza1.AddTopping(toppingToAdd.Name); pizza1.Price += toppingToAdd.Price; // 此时为decimal数值相加,结果正确 } else if (selectedItem is Burger burger) { burger.AddGarnish(toppingToAdd.Name); burger.Price += toppingToAdd.Price; }
4. 调整文件保存时的价格输出
在SaveMenuToFile方法中,按需格式化decimal数值为货币字符串:
// 保存Pizza信息的代码修正 sb.AppendLine($"Pizza:< Name:{pizza.Name},Toppings: [{string.Join(", ", pizza.GetToppings())}],Price: £{pizza.Price:F2} >"); // 保存Toppings信息的代码修正 sb.Append(string.Join(", ", _topping.Select(t => $"<{t.Name},£{t.Price:F2}>")));
额外建议
- 永远用
decimal处理货币计算,避免浮点类型的精度误差。 - 严格分离数据存储和显示逻辑:数值类型存数据,字符串格式化仅用于用户展示或输出文件。
- 如果需要从货币字符串解析数值(比如从配置文件读取),使用指定文化的
decimal.TryParse:
string priceStr = "£5.00"; if (decimal.TryParse(priceStr, NumberStyles.Currency, new CultureInfo("en-GB"), out decimal price)) { // 成功解析为decimal数值 }
内容的提问来源于stack exchange,提问作者Legois
相关产品推荐
相关产品推荐

