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

如何更优存储可用食材类信息?现有C#实现方案求改进

优化C#食材信息存储方案的探讨

当前实现代码

public static class IngredientDataStorage
{

    public static List<Ingredient> GetIngredientList()
    {
    List<Ingredient> availIngredientsList = new List<Ingredient>()
       {
        new Butter(), new Cinnamon(), new Chocolate()
       };
    return availIngredientsList;
    }

   public static Dictionary<int, Ingredient> GetIngredientDictionary()
    {
       Dictionary<int, Ingredient> availIngDict = new Dictionary<int, Ingredient>()
      {
       {3, new Chocolate() },
       {2, new Butter() },
       {4, new Cinnamon() }
      };
      return availIngDict;
   }


public static List<int> GetIDList()
  {
    var IDList = new List<int>();
    foreach (Ingredient ingredient in GetIngredientList())
    {
        IDList.Add(ingredient.ID);
    }
    return IDList;
   }

public static void PrintAvailIngredients()
  {
    List<Ingredient> ingredientList = IngredientDataStorage.GetIngredientList();

    foreach (Ingredient ingredient in ingredientList)
    {
        ingredient.PrintInfo();
    }
  }
}

问题描述

我目前有Butter、Cinnamon、Chocolate三个食材类,通过列表、字典存储它们的实例,还实现了获取ID列表及打印食材信息的方法,请问是否存在更优的可用食材信息存储方式?


优化方案

核心问题分析

当前实现存在几个明显弊端:

  • 每次调用获取集合的方法都会重新创建食材实例,既浪费内存,又可能导致同一食材的实例状态不一致(若食材有可变属性)。
  • 列表和字典的数据是重复维护的,新增或修改食材时需要同步更新两个集合,极易出现数据不一致。
  • GetIDList()需要遍历列表生成,效率低下,且依赖重复创建的实例。

具体优化实现

1. 单例化核心存储集合

将食材实例只初始化一次,存储在静态字段中,优先用字典作为核心存储(按ID查询是高频场景),列表可通过字典的Values属性直接获取,无需单独维护:

public static class IngredientDataStorage
{
    // 核心存储:仅初始化一次的字典
    private static readonly Dictionary<int, Ingredient> _ingredients = new Dictionary<int, Ingredient>()
    {
        {2, new Butter() },
        {3, new Chocolate() },
        {4, new Cinnamon() }
    };

    // 返回只读字典包装,防止外部修改内部集合
    public static IReadOnlyDictionary<int, Ingredient> GetIngredientDictionary()
    {
        return new ReadOnlyDictionary<int, Ingredient>(_ingredients);
    }

    // 通过字典Values获取只读列表,无需单独维护
    public static IReadOnlyList<Ingredient> GetIngredientList()
    {
        return _ingredients.Values.ToList().AsReadOnly();
    }

    // 直接从字典Keys获取ID列表,无需遍历
    public static IReadOnlyList<int> GetIDList()
    {
        return _ingredients.Keys.ToList().AsReadOnly();
    }

    public static void PrintAvailIngredients()
    {
        foreach (var ingredient in _ingredients.Values)
        {
            ingredient.PrintInfo();
        }
    }
}

2. 自动扫描注册食材(扩展性优化)

如果后续需要新增大量食材类,可通过反射自动扫描程序集中的食材类型,实现自动注册,避免手动维护字典:

public static class IngredientDataStorage
{
    private static readonly Dictionary<int, Ingredient> _ingredients;

    static IngredientDataStorage()
    {
        _ingredients = new Dictionary<int, Ingredient>();
        // 扫描当前程序集中所有继承自Ingredient的非抽象类
        var ingredientTypes = typeof(Ingredient).Assembly.GetTypes()
            .Where(t => t.IsSubclassOf(typeof(Ingredient)) && !t.IsAbstract);
        
        foreach (var type in ingredientTypes)
        {
            // 假设所有食材类都有无参构造函数
            var ingredient = (Ingredient)Activator.CreateInstance(type);
            if (!_ingredients.ContainsKey(ingredient.ID))
            {
                _ingredients.Add(ingredient.ID, ingredient);
            }
        }
    }

    // 其余方法同方案1...
}

3. 食材类单例化(实例一致性优化)

如果需要确保每个食材只有一个实例,可在食材类本身实现单例,再统一注册到存储类:

public abstract class Ingredient
{
    public abstract int ID { get; }
    public abstract void PrintInfo();
}

public class Butter : Ingredient
{
    // 食材单例实例
    public static readonly Butter Instance = new Butter();
    private Butter() {}

    public override int ID => 2;
    public override void PrintInfo() => Console.WriteLine("Butter (ID: 2)");
}

// Cinnamon、Chocolate类同理实现单例模式

public static class IngredientDataStorage
{
    private static readonly Dictionary<int, Ingredient> _ingredients = new Dictionary<int, Ingredient>()
    {
        {Butter.Instance.ID, Butter.Instance},
        {Chocolate.Instance.ID, Chocolate.Instance},
        {Cinnamon.Instance.ID, Cinnamon.Instance}
    };

    // 其余方法同方案1...
}

优化后的优势

  • 性能提升:避免重复创建实例,集合查询与遍历效率更高。
  • 数据一致性:核心数据仅维护一份,新增/修改食材只需更新字典。
  • 安全性:通过只读包装暴露集合,防止外部代码意外修改内部数据。
  • 扩展性:反射扫描或单例模式能大幅降低新增食材时的维护成本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 11:27:44