基于If语句实现三类咖啡下单逻辑的C#技术问询
咖啡下单控制台代码的问题分析与优化方案
现有代码的核心问题
1. 流程逻辑错误
- 选择Cappuccino后,代码重复执行姓名和咖啡选择的询问,强制重启用户下单流程,完全不符合正常交互逻辑。
- Latte分支中嵌套的
else if (choice ==3)永远无法触发,因为它处于choice ==2的分支内,条件永远不成立。 - Americano的代码直接写在Latte分支末尾,无论用户是否选择Latte,这部分代码都会执行,逻辑彻底混乱。
2. 冗余重复代码
每个咖啡品类(Cappuccino、Latte、Americano)的尺寸选择、热奶询问、价格展示逻辑几乎完全一致,没有复用机制,后期修改价格或规则需多处改动,维护成本极高。
3. 输入处理缺乏安全性
使用Convert.ToInt32()、Convert.ToChar()处理用户输入时,若用户输入非预期值(比如用字母代替数字选咖啡),会直接抛出异常导致程序崩溃,无错误提示或重试逻辑。
4. 变量管理混乱
- 存在大量未使用的冗余变量:
cap、latt、amer、discount等从未被赋值或使用,属于无效代码。 - 咖啡价格以单个变量形式定义(如
cappucciniosmall),无结构化管理,无法统一维护价格体系。 - 询问热奶选择的
milk变量获取值后,无任何后续处理逻辑,功能完全无效。
5. 逻辑错误的价格覆盖
展示咖啡价格后,代码执行cappucciniosmall = Convert.ToDouble(Console.ReadLine());,用用户输入值覆盖原本的价格变量,完全不符合下单逻辑(应是确认订单而非修改价格)。
6. 不必要的依赖
代码引用System.Drawing命名空间,但全程未使用该空间下的任何功能,增加了不必要的程序依赖。
优化后的代码实现
通过结构化设计、逻辑复用、输入验证修复上述问题:
using System; namespace Group_cafe7 { // 定义咖啡尺寸枚举 public enum CoffeeSize { Small, Medium, Large } // 定义咖啡类,封装品类、尺寸价格、热奶加价规则 public class Coffee { public string Name { get; set; } public decimal SmallPrice { get; set; } public decimal MediumPrice { get; set; } public decimal LargePrice { get; set; } public decimal HotMilkExtra { get; set; } = 2.0m; // 添加热奶的额外费用 } class Program { static void Main(string[] args) { // 初始化咖啡菜单 var menu = new[] { new Coffee { Name = "Cappuccino", SmallPrice = 13.50m, MediumPrice = 18.00m, LargePrice = 25.50m }, new Coffee { Name = "Latte", SmallPrice = 15.50m, MediumPrice = 20.00m, LargePrice = 27.50m }, new Coffee { Name = "Americano", SmallPrice = 17.50m, MediumPrice = 22.00m, LargePrice = 29.50m } }; // 获取用户姓名 Console.WriteLine("Hello, Please enter your name: "); string userName = Console.ReadLine(); // 选择咖啡品类,带输入验证 Coffee selectedCoffee = null; while (selectedCoffee == null) { Console.WriteLine("\nPlease enter your choice number:"); Console.WriteLine("1. Cappuccino 2. Latte 3. Americano"); if (int.TryParse(Console.ReadLine(), out int choice) && choice >=1 && choice <=3) { selectedCoffee = menu[choice -1]; } else { Console.WriteLine("Invalid input! Please enter a number between 1 and 3."); } } // 选择咖啡尺寸,带输入验证 CoffeeSize selectedSize = default; decimal basePrice = 0; while (basePrice == 0) { Console.WriteLine($"\nChoose size for {selectedCoffee.Name}:"); Console.WriteLine("S (Small), M (Medium), L (Large)"); string sizeInput = Console.ReadLine()?.Trim().ToUpper(); switch (sizeInput) { case "S": selectedSize = CoffeeSize.Small; basePrice = selectedCoffee.SmallPrice; break; case "M": selectedSize = CoffeeSize.Medium; basePrice = selectedCoffee.MediumPrice; break; case "L": selectedSize = CoffeeSize.Large; basePrice = selectedCoffee.LargePrice; break; default: Console.WriteLine("Invalid input! Please enter S, M, or L."); break; } } // 询问是否添加热奶,带输入验证 bool addHotMilk = false; while (true) { Console.WriteLine("\nAdd Hotmilk? (yes/no)"); string milkInput = Console.ReadLine()?.Trim().ToLower(); if (milkInput == "yes") { addHotMilk = true; break; } else if (milkInput == "no") { addHotMilk = false; break; } else { Console.WriteLine("Invalid input! Please enter yes or no."); } } // 计算最终价格 decimal totalPrice = basePrice + (addHotMilk ? selectedCoffee.HotMilkExtra : 0); // 输出订单确认 Console.WriteLine($"\n--- Order Confirmation for {userName} ---"); Console.WriteLine($"Coffee: {selectedCoffee.Name}"); Console.WriteLine($"Size: {selectedSize}"); Console.WriteLine($"Add Hotmilk: {(addHotMilk ? "Yes" : "No")}"); Console.WriteLine($"Total Price: ${totalPrice:F2}"); Console.WriteLine("Thank you for your order!"); } } }
优化点说明
- 结构化设计:用
Coffee类封装咖啡信息,CoffeeSize枚举统一尺寸选项,便于维护和扩展新品类。 - 输入验证:使用
int.TryParse()和循环重试机制,避免非法输入导致程序崩溃。 - 逻辑复用:所有咖啡品类共用同一套选择尺寸、询问热奶的逻辑,大幅减少代码冗余。
- 流程修复:修正原有流程的错误,确保用户按正常下单流程完成操作。
- 功能完善:实现热奶添加的价格计算,完成完整的订单确认输出。
- 清理冗余:移除未使用的变量和不必要的命名空间引用。
内容的提问来源于stack exchange,提问作者Saadiq Karriem
相关产品推荐
相关产品推荐

