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

如何编写泛型方法填充自动售货机中不同类型Snack的列表?

解决方案

你当前的FillWithProducts方法硬编码了Drink的判断逻辑,新增Sweets类型时还要修改方法,违背了开闭原则。可以通过以下两种方式优化,彻底避免重复代码:

方式一:用字典维护类型与列表的映射

在VendingMachine类里定义一个字典,把每种Snack子类对应的列表存起来,泛型方法直接通过类型找到对应列表,不用硬编码判断:

public class VendingMachine
{
    // 各产品列表
    private List<Drink> _drinks = new List<Drink>();
    private List<Sweets> _sweets = new List<Sweets>();
    
    // 公共只读属性
    public List<Drink> Drinks => _drinks;
    public List<Sweets> Sweets => _sweets;
    
    // 类型到对应列表的映射字典
    private readonly Dictionary<Type, IList> _productLists;

    public VendingMachine()
    {
        // 初始化映射关系
        _productLists = new Dictionary<Type, IList>
        {
            { typeof(Drink), _drinks },
            { typeof(Sweets), _sweets }
        };
    }

    private void FillWithProducts<Product>(params Product[] products) where Product : Snack
    {
        if (_productLists.TryGetValue(typeof(Product), out var targetList))
        {
            foreach (var product in products)
            {
                ((IList<Product>)targetList).Add(product);
            }
        }
    }
}

这种方式扩展性极强,新增Snack子类时,只需要添加对应的列表属性和字典映射,完全不用修改填充方法的逻辑。

方式二:泛型辅助方法+模式匹配

如果不想用字典,也可以写一个泛型辅助方法来匹配对应类型的列表,填充方法直接复用逻辑:

public class VendingMachine
{
    private List<Drink> _drinks = new List<Drink>();
    private List<Sweets> _sweets = new List<Sweets>();
    
    public List<Drink> Drinks => _drinks;
    public List<Sweets> Sweets => _sweets;

    private void FillWithProducts<Product>(params Product[] products) where Product : Snack
    {
        var targetList = GetProductList<Product>();
        targetList?.AddRange(products);
    }

    private List<Product> GetProductList<Product>() where Product : Snack
    {
        return typeof(Product) switch
        {
            Type t when t == typeof(Drink) => _drinks as List<Product>,
            Type t when t == typeof(Sweets) => _sweets as List<Product>,
            _ => null
        };
    }
}

这里用了C#的模式匹配语法,比原有的if判断更简洁。新增类型时,只需要在GetProductList的switch里加一个分支,填充方法的逻辑完全不用改动。

补充说明

两种方案都遵循了DRY(Don't Repeat Yourself)原则,避免为每种产品类型编写重复的填充逻辑。如果后续会频繁新增Snack子类,优先选方式一;类型较少的场景下,方式二更直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:20:50