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

如何实现FruitsCombined与Fruits枚举的关联映射及筛选优化?

枚举绑定ComboBox后的多值映射优化方案

问题背景

我定义了两个枚举类型:

public enum Fruits
{
    Apple = 1,
    Banana = 2,
    Strawberry = 3,
    Blueberry = 4
}

public enum FruitsCombined
{
    Apple = 1,
    Banana = 2,
    Berries = 0  //Strawberry和Blueberry的合并项
}

将ComboBox绑定到FruitsCombined枚举后,需要在后台逻辑中实现:选中Berries选项时,匹配Fruits枚举里的Strawberry(3)和Blueberry(4);选中其他选项时,直接匹配对应数值。现有实现代码如下,希望找到更优方案:

if ((int)cboFilterFruitType.SelectedValue == 0)
{
    order = order.FindAll(o => o.FruitID == 3 || o.FruitID == 4);
}
else
{
    order = order.FindAll(o => o.FruitID == (int) cboFilterFruitType.SelectedValue);
}

优化方案

方案一:使用映射字典(推荐,简单直观)

提前定义FruitsCombined到对应Fruits集合的映射关系,后续过滤时直接通过字典取值,避免硬编码数值和条件判断:

// 定义映射字典,可放在类的静态构造函数或全局初始化处
private static readonly Dictionary<FruitsCombined, IEnumerable<Fruits>> _fruitMapping = new()
{
    [FruitsCombined.Apple] = new[] { Fruits.Apple },
    [FruitsCombined.Banana] = new[] { Fruits.Banana },
    [FruitsCombined.Berries] = new[] { Fruits.Strawberry, Fruits.Blueberry }
};

// 过滤逻辑
var selectedType = (FruitsCombined)cboFilterFruitType.SelectedValue;
var targetFruits = _fruitMapping[selectedType];
order = order.FindAll(o => targetFruits.Contains((Fruits)o.FruitID));

优势:逻辑清晰,新增合并项或修改映射关系时,只需更新字典,无需改动过滤代码;避免直接使用魔法数值,可读性更高。

方案二:自定义特性+反射(适合扩展性要求高的场景)

通过自定义特性标记FruitsCombined枚举项对应的Fruits值,再用反射获取特性信息,实现解耦:

  1. 定义自定义特性:
[AttributeUsage(AttributeTargets.Field)]
public class MapToFruitsAttribute : Attribute
{
    public IEnumerable<Fruits> TargetFruits { get; }

    public MapToFruitsAttribute(params Fruits[] targetFruits)
    {
        TargetFruits = targetFruits;
    }
}
  1. 给FruitsCombined枚举添加特性:
public enum FruitsCombined
{
    [MapToFruits(Fruits.Apple)]
    Apple = 1,
    [MapToFruits(Fruits.Banana)]
    Banana = 2,
    [MapToFruits(Fruits.Strawberry, Fruits.Blueberry)]
    Berries = 0
}
  1. 编写辅助方法获取映射的水果集合:
public static IEnumerable<Fruits> GetTargetFruits(this FruitsCombined combined)
{
    var fieldInfo = combined.GetType().GetField(combined.ToString());
    var attribute = fieldInfo.GetCustomAttribute<MapToFruitsAttribute>();
    return attribute?.TargetFruits ?? Enumerable.Empty<Fruits>();
}
  1. 过滤逻辑:
var selectedType = (FruitsCombined)cboFilterFruitType.SelectedValue;
var targetFruits = selectedType.GetTargetFruits();
order = order.FindAll(o => targetFruits.Contains((Fruits)o.FruitID));

优势:映射关系直接标注在枚举项上,代码侵入性低;新增枚举项时只需添加特性即可,无需修改其他逻辑。

方案三:扩展方法封装逻辑

如果不想引入字典或特性,可将映射逻辑封装到扩展方法中,让过滤代码更简洁:

public static IEnumerable<Fruits> ToTargetFruits(this FruitsCombined combined)
{
    return combined switch
    {
        FruitsCombined.Apple => new[] { Fruits.Apple },
        FruitsCombined.Banana => new[] { Fruits.Banana },
        FruitsCombined.Berries => new[] { Fruits.Strawberry, Fruits.Blueberry },
        _ => Enumerable.Empty<Fruits>()
    };
}

// 过滤逻辑
var selectedType = (FruitsCombined)cboFilterFruitType.SelectedValue;
var targetFruits = selectedType.ToTargetFruits();
order = order.FindAll(o => targetFruits.Contains((Fruits)o.FruitID));

优势:逻辑集中,过滤代码干净;使用模式匹配语法,可读性优于传统if-else。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:40:42