C#如何将两个不同类的实例添加到同一个List集合并正常打印内容
问题修复方案
打印异常核心原因及代码问题整理
- ToString方法中错误调用
ToList():字符串类型的town/country被转为List<char>,拼接输出时会打印集合类型名而非实际地址内容 - 特殊订单分支逻辑错误:选择S(特殊订单)时仍然实例化
NormalOrder,SpecialOrder类完全未被使用 - 执行逻辑顺序错误:收件地址类型判断写在foreach循环内部,每遍历一个订单就重复判断一次用户输入,输入错误时会重复打印N次错误提示(N为订单总量)
- 大小写匹配逻辑缺失:提示输入T=Town,代码判断条件为小写
t,用户输入大写T会被判定为输入错误 - 程序无退出路径:
close变量始终为true,循环无法正常终止 - 缺少类型筛选逻辑:选择查看城镇/国家地址时,未过滤对应订单类型,所有订单都会被输出
修复后的代码示例
List<Order> orders = new List<Order>(); bool close = true; while (close) { Console.WriteLine("What type of order is this?(N=Normal/S=Special/#=End)"); string parcel = Console.ReadLine().Trim(); string name, location, date; int number; if (parcel.Equals("N", StringComparison.OrdinalIgnoreCase)) { Console.Write("Enter the name of your order: "); name = Console.ReadLine(); Console.Write("Enter your order number: "); number = Convert.ToInt32(Console.ReadLine()); Console.Write("Enter your order date: "); date = Console.ReadLine(); Console.Write("Enter your town: "); location = Console.ReadLine(); orders.Add(new NormalOrder(name, number, date, location)); } else if (parcel.Equals("S", StringComparison.OrdinalIgnoreCase)) { Console.Write("Enter the name of your order: "); name = Console.ReadLine(); Console.Write("Enter your order number: "); number = Convert.ToInt32(Console.ReadLine()); Console.Write("Enter your order date: "); date = Console.ReadLine(); Console.Write("Enter your country: "); location = Console.ReadLine(); // 修正为实例化SpecialOrder orders.Add(new SpecialOrder(name, number, date, location)); } else if (parcel == "#") { Console.WriteLine("Do you want to see which countries or town your sent your parcel to?(C=Country/T=Town/E=Exit)"); string shipping = Console.ReadLine().Trim(); // 先判断输入类型再遍历订单 if (shipping.Equals("T", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("=== 城镇地址订单列表 ==="); foreach (var order in orders.OfType<NormalOrder>()) { Console.WriteLine(order); Console.WriteLine("-------------------"); } } else if (shipping.Equals("C", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("=== 国家地址订单列表 ==="); foreach (var order in orders.OfType<SpecialOrder>()) { Console.WriteLine(order); Console.WriteLine("-------------------"); } } else if (shipping.Equals("E", StringComparison.OrdinalIgnoreCase)) { // 退出循环 close = false; Console.WriteLine("程序即将退出"); } else { Console.WriteLine("Incorrect input, try again!"); } } else { Console.WriteLine("Incorrect input, try again!"); } } class Order { protected string orderName { get; set; } protected int orderNumber { get; set; } protected string orderDate { get; set; } } class NormalOrder : Order { private string town { get; set; } public NormalOrder(string orderName, int orderNumber, string orderDate, string town) { this.orderName = orderName; this.orderNumber = orderNumber; this.orderDate = orderDate; this.town = town; } public override string ToString() { // 删掉多余的ToList()调用 return $"Order name: {orderName}\nOrder number: {orderNumber}\nOrder date: {orderDate}\nOrder location: {town}"; } } class SpecialOrder : Order { private string country; public SpecialOrder(string orderName, int orderNumber, string orderDate, string country) { this.orderName = orderName; this.orderNumber = orderNumber; this.orderDate = orderDate; this.country = country; } public override string ToString() { // 删掉多余的ToList()调用 return $"Order name: {orderName}\nOrder number: {orderNumber}\nOrder date: {orderDate}\nOrder location: {country}"; } }
额外优化建议
- 订单号输入可增加异常捕获,避免用户输入非数字内容导致程序崩溃
- 订单日期可改用
DateTime类型存储,方便后续做时间维度的筛选 - 可给Order基类增加抽象的
GetLocation()方法,无需依赖OfType做类型筛选
内容的提问来源于stack exchange,提问作者Zeorth
相关产品推荐
相关产品推荐

