如何优化根据字符串匹配获取SEWorkflowStates属性值的实现?
问题背景
相关类与枚举定义如下:
public class SEWorkflow { public SEActions SEAction { get; set; } public string nextuser { get; set; } } public class SEActions { public SEWorkflowStates OnApprove { get; set; } public SEWorkflowStates OnReject { get; set; } public SEWorkflowStates OnSubmit { get; set; } } public enum SEWorkflowStates { Nothing, DonotDisturb, }
我持有SEWorkflow实例,还有值为OnApprove/OnReject/OnSubmit的字符串变量action,目前通过if分支实现根据action匹配SEActions中对应属性、获取SEWorkflowStates值:
public SEWorkflowStates mapper(SEWorkflow workflow, string action) { // action = OnApprove or OnReject or OnSubmit if(action == "OnApprove") { return workflow.SEActions.OnApprove; } if(action == "OnReject") { return workflow.SEActions.OnReject; } if(action == "OnSubmit") { return workflow.SEActions.OnSubmit; } return SEWorkflowStates.Nothing; }
但这种if写法较为繁琐,请问是否有更优的实现方式?
优化方案
1. 字典映射(推荐:性能稳定、易维护)
提前创建静态字典,将字符串action映射到属性获取委托,后续新增属性仅需更新字典:
// 作为类的静态成员,避免重复创建 private static readonly Dictionary<string, Func<SEActions, SEWorkflowStates>> _actionMappings = new() { ["OnApprove"] = actions => actions.OnApprove, ["OnReject"] = actions => actions.OnReject, ["OnSubmit"] = actions => actions.OnSubmit }; public SEWorkflowStates mapper(SEWorkflow workflow, string action) { if (_actionMappings.TryGetValue(action, out var getter)) { return getter(workflow.SEActions); } // 处理无效action的默认逻辑 return SEWorkflowStates.Nothing; }
2. 反射+缓存(适合属性较多场景)
通过反射根据属性名直接取值,搭配缓存避免重复反射开销:
private static readonly Dictionary<string, PropertyInfo> _propertyCache = new(); public SEWorkflowStates mapper(SEWorkflow workflow, string action) { if (!_propertyCache.TryGetValue(action, out var property)) { property = typeof(SEActions).GetProperty(action); if (property == null || property.PropertyType != typeof(SEWorkflowStates)) { return SEWorkflowStates.Nothing; } _propertyCache[action] = property; } return (SEWorkflowStates)property.GetValue(workflow.SEActions); }
3. 枚举替代字符串(从根源优化)
若可修改方法参数类型,定义对应操作的枚举,用C#模式匹配简化逻辑,还能避免字符串拼写错误:
public enum WorkflowAction { OnApprove, OnReject, OnSubmit } public SEWorkflowStates mapper(SEWorkflow workflow, WorkflowAction action) { return action switch { WorkflowAction.OnApprove => workflow.SEActions.OnApprove, WorkflowAction.OnReject => workflow.SEActions.OnReject, WorkflowAction.OnSubmit => workflow.SEActions.OnSubmit, _ => SEWorkflowStates.Nothing }; }
内容的提问来源于stack exchange,提问作者Venkat
相关产品推荐
相关产品推荐

