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

如何通过泛型枚举优化C#函数以消除switch分支?

如何消除枚举判断的Switch语句?

我当前用Switch语句根据SubGroups枚举值来遍历对应的子枚举类型,实现将面板对应组的所有输入置为false,再激活指定的子项。代码能正常运行,但想找更优方案,请问能不能通过传递泛型枚举类型来消除Switch?或者有没有枚举以外的实现方式?

原代码:

public static void ShowGroupSub(List<BasicTriListWithSmartObject> panels, uint type,uint sub)
{
    foreach (BasicTriListWithSmartObject panel in panels)
    {
        switch(type)
        {
            case (uint)SubGroups.Control:
                foreach (uint index in Enum.GetValues(typeof(ControlSubs)))
                    panel.BooleanInput[index].BoolValue = false;
                panel.BooleanInput[sub].BoolValue = true;
                break;
            case (uint)SubGroups.Presets:
                foreach (uint index in Enum.GetValues(typeof(PresetSubs)))
                    panel.BooleanInput[index].BoolValue = false;
                panel.BooleanInput[sub].BoolValue = true;
                break;
            case (uint)SubGroups.VideoCall:
                foreach (uint index in Enum.GetValues(typeof(VideoCallSubs)))
                    panel.BooleanInput[index].BoolValue = false;
                panel.BooleanInput[sub].BoolValue = true;
                break;
        }
    }
}

public enum SubGroups : uint
{
    Control      = 1,
    Presets      = 2,
    VideoCall    = 3
}

public enum ControlSubs : uint
{
    Bluray = 60,
    PC = 61,
    Laptop = 62,
    AirMedia = 63,
    ClickShare = 64,
    CamControl = 65,
    DocCam = 66,
    CATV = 67,
}

public enum PresetSubs : uint
{
    Main = 60,
    Edit = 61
}

public enum VideoCallSubs : uint
{
    Contacts = 271,
    Keyboard = 272,
    Camera = 273,
    CallActive = 274,
    AddCallContacts = 275,
    AddCallKeyboard = 276
}

方案一:泛型+映射字典消除Switch

通过建立SubGroups与子枚举类型的映射,结合泛型方法提取重复逻辑,完全移除Switch:

// 提前定义映射字典,关联主枚举和对应的子枚举类型
private static readonly Dictionary<SubGroups, Type> _subGroupEnumMap = new()
{
    { SubGroups.Control, typeof(ControlSubs) },
    { SubGroups.Presets, typeof(PresetSubs) },
    { SubGroups.VideoCall, typeof(VideoCallSubs) }
};

public static void ShowGroupSub(List<BasicTriListWithSmartObject> panels, SubGroups type, uint sub)
{
    // 处理无效的组类型
    if (!_subGroupEnumMap.TryGetValue(type, out var subEnumType))
        return;

    // 调用泛型方法处理核心逻辑
    ToggleSubGroup(panels, subEnumType, sub);
}

private static void ToggleSubGroup(List<BasicTriListWithSmartObject> panels, Type subEnumType, uint sub)
{
    // 可选:验证sub是否属于当前子枚举,避免无效索引报错
    if (!Enum.IsDefined(subEnumType, sub))
        throw new ArgumentOutOfRangeException(nameof(sub), "该子项不属于当前组");

    foreach (var panel in panels)
    {
        // 遍历子枚举所有值,置为false
        foreach (uint index in Enum.GetValues(subEnumType).Cast<uint>())
            panel.BooleanInput[index].BoolValue = false;
        // 激活目标子项
        panel.BooleanInput[sub].BoolValue = true;
    }
}

后续新增SubGroups枚举值时,只需要在字典中添加一行映射即可,扩展性大幅提升。同时把参数uint type改为SubGroups type,避免强制转换,类型更安全。

方案二:策略模式(面向对象替代方案)

如果想彻底脱离枚举的限制,可将每组逻辑封装为独立策略类,实现完全的解耦:

// 定义策略接口,规范组操作
public interface ISubGroupStrategy
{
    IEnumerable<uint> GetAllSubIndices();
    bool IsValidSub(uint sub);
}

// 实现Control组策略
public class ControlSubGroupStrategy : ISubGroupStrategy
{
    public IEnumerable<uint> GetAllSubIndices() => Enum.GetValues(typeof(ControlSubs)).Cast<uint>();
    public bool IsValidSub(uint sub) => Enum.IsDefined(typeof(ControlSubs), sub);
}

// 实现Presets组策略
public class PresetSubGroupStrategy : ISubGroupStrategy
{
    public IEnumerable<uint> GetAllSubIndices() => Enum.GetValues(typeof(PresetSubs)).Cast<uint>();
    public bool IsValidSub(uint sub) => Enum.IsDefined(typeof(PresetSubs), sub);
}

// 实现VideoCall组策略
public class VideoCallSubGroupStrategy : ISubGroupStrategy
{
    public IEnumerable<uint> GetAllSubIndices() => Enum.GetValues(typeof(VideoCallSubs)).Cast<uint>();
    public bool IsValidSub(uint sub) => Enum.IsDefined(typeof(VideoCallSubs), sub);
}

// 映射主枚举到对应策略
private static readonly Dictionary<SubGroups, ISubGroupStrategy> _subGroupStrategies = new()
{
    { SubGroups.Control, new ControlSubGroupStrategy() },
    { SubGroups.Presets, new PresetSubGroupStrategy() },
    { SubGroups.VideoCall, new VideoCallSubGroupStrategy() }
};

public static void ShowGroupSub(List<BasicTriListWithSmartObject> panels, SubGroups type, uint sub)
{
    if (!_subGroupStrategies.TryGetValue(type, out var strategy))
        return;

    if (!strategy.IsValidSub(sub))
        throw new ArgumentOutOfRangeException(nameof(sub));

    foreach (var panel in panels)
    {
        foreach (var index in strategy.GetAllSubIndices())
            panel.BooleanInput[index].BoolValue = false;
        panel.BooleanInput[sub].BoolValue = true;
    }
}

这种方式适合逻辑复杂的场景,新增组只需添加对应的策略类和字典映射,各组逻辑完全隔离,维护性更好。

额外优化建议

  • 缓存枚举值:如果子枚举不会动态修改,可提前将Enum.GetValues的结果缓存起来,避免重复调用的性能开销。
  • 类型安全:始终使用枚举类型而非uint作为参数,减少类型转换错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 03:22:28