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

C#中如何创建含不同子类Tuple列表的列表以简化商店代码

解决方法:利用LINQ投影+协变接口统一集合

核心思路是把每个子类物品列表,通过LINQ转换成统一的Item基类+价格的枚举集合,然后把这些集合放到支持协变的容器里,就能用嵌套foreach统一处理了,完全不用修改Item基类或新建额外类。

代码示例

假设你的类结构如下:

public class Item { /* 基类属性,比如Name、Id等 */ }
public class TestItem : Item { }
public class AnotherItem : Item { }

public class ShopInventory
{
    public List<Tuple<TestItem, int>> TestItems { get; set; } = new();
    public List<Tuple<AnotherItem, int>> AnotherItems { get; set; } = new();

    // 统一展示所有商店物品的方法
    public void DisplayAllShopItems()
    {
        // 将各个子类列表转换为统一的(Item, int)枚举集合
        var allShopItemGroups = new List<IEnumerable<(Item Item, int Price)>>
        {
            TestItems.Select(t => ((Item)t.Item1, t.Item2)),
            AnotherItems.Select(t => ((Item)t.Item1, t.Item2))
        };

        // 嵌套foreach统一处理所有物品
        foreach (var itemGroup in allShopItemGroups)
        {
            foreach (var (item, price) in itemGroup)
            {
                // 这里写统一的展示逻辑,比如
                Console.WriteLine($"物品名称:{item.Name},售价:{price}金币");
            }
        }
    }
}

更简化的方式:直接合并成单个集合

如果不需要区分原列表的分组,还可以直接把所有物品合并成一个枚举集合,省去嵌套循环:

public void DisplayAllShopItems()
{
    var allItems = TestItems.Select(t => ((Item)t.Item1, t.Item2))
                            .Concat(AnotherItems.Select(t => ((Item)t.Item1, t.Item2)));

    foreach (var (item, price) in allItems)
    {
        Console.WriteLine($"物品名称:{item.Name},售价:{price}金币");
    }
}

为什么原来的List<List<Tuple<Item,int>>>不行?

泛型列表List<T>是不变类型,List<Tuple<TestItem, int>>和List<Tuple<Item, int>>是完全独立的类型,不存在继承关系,所以无法直接添加。而IEnumerable<T>是协变类型(因为T是out参数),加上我们用Select把每个元素转换成基类类型,就能实现类型兼容。

额外优化:改用值元组替代Tuple

如果你的项目使用C# 7.0及以上版本,建议把原来的Tuple换成值元组,语法更简洁,转换也更直观:

// 修改库存列表的类型
public List<(TestItem Item, int Price)> TestItems { get; set; } = new();
public List<(AnotherItem Item, int Price)> AnotherItems { get; set; } = new();

// 转换逻辑更清晰
var allItems = TestItems.Select(t => ((Item)t.Item, t.Price))
                        .Concat(AnotherItems.Select(t => ((Item)t.Item, t.Price)));

内容的提问来源于stack exchange,提问作者Aijokoryu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 05:47:29