You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多类重写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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:42:07