多类重写ToString()方法异常:Inventory实例未执行对应重写方法
问题分析与解决方案
首先,咱们来拆解你遇到的问题:你看到的ProductCost值,其实并不是直接调用了Item的ToString,而是你的Inventory类的ToString方法返回的结果里包含了Item的ToString输出。之所以只看到ProductCost,是因为你的Inventory代码里存在几个关键问题:
核心问题列表
- 未定义
name变量:你的Inventory.ToString()里用了name,但类里根本没声明这个字段/属性,编译时应该会报错,就算勉强运行,name也是null,导致最终只返回stuff部分(也就是所有Item.ToString()的拼接)。 - 字段与属性同名冲突:你同时定义了
private List<Item> list和public List<Item> list { get; set; },这会导致编译错误,或者编译器无法区分你要访问的是字段还是属性,最终导致列表数据异常。 - 字符串拼接效率低下:直接用
stuff += items.ToString()会频繁创建新字符串,虽然不影响功能,但不是最佳实践。
修复后的完整代码
1. 修正Inventory类
using System.Collections.Generic; using System.Text; public class Inventory { // 私有字段用下划线前缀,和属性区分开 private List<Item> _items = new List<Item>(); // 公共属性命名用 PascalCase,避免和字段冲突 public List<Item> Items { get; set; } // 添加缺失的 Name 属性,用来显示你想要的前缀 public string Name { get; set; } public Inventory() { // 初始化 Name Name = "产品清单:"; // 初始化物品列表 _items = new List<Item>() { new Item("iPod"), new Item("Motorolla"), new Item("Samsung"), new Item("Nokia") }; // 让属性指向私有字段(或者直接用自动属性,去掉私有字段也可以) Items = _items; } public override string ToString() { // 用 StringBuilder 优化字符串拼接 var sb = new StringBuilder(); sb.Append(Name); // 遍历每个物品,拼接它们的ToString结果 foreach (var item in _items) { sb.Append($" {item.ToString()}"); // 这里可以按需调整格式,比如换行 } return sb.ToString(); } }
2. 完善Item类(补充你缺失的构造函数和ProductCost逻辑)
public class Item { public string ProductName { get; set; } // 补充构造函数,接收产品名称 public Item(string productName) { ProductName = productName; } // 实现 ProductCost 方法,根据产品名称返回对应成本 public decimal ProductCost() { return ProductName switch { "iPod" => 199.99m, "Motorolla" => 99.99m, "Samsung" => 299.99m, "Nokia" => 49.99m, _ => 0m }; } public override string ToString() => $"{ProductName} ({ProductCost():C})"; }
3. Form代码保持不变(或者可以调整显示格式)
private void Form1_Load(object sender, EventArgs e) { var products = new Inventory(); lstBox.Items.Add(products); // 现在会显示 "产品清单:iPod ($199.99) Motorolla ($99.99) ..." }
为什么你之前会看到ProductCost的值?
你误会了——ListBox确实调用了Inventory的ToString方法,但因为你的Inventory类里没有name字段,name是null,所以最终返回的只有stuff(也就是所有Item.ToString()的拼接结果)。而Item.ToString()返回的就是ProductCost()的字符串,所以你看到的其实是Inventory.ToString()的输出,只是缺少了name前缀而已。
现在修复后,你就能看到name + stuff的完整结果了,同时也保留了两个类的ToString实现。
内容的提问来源于stack exchange,提问作者iStudent
相关产品推荐
相关产品推荐

