C#动态匹配IList<T>元素类型 优化多分支if else判断方案咨询
优化方案
你当前所有分支的处理逻辑完全一致,仅泛型参数存在差异,无需用if-else硬编码匹配类型,以下是两种可落地的优化方案:
方案1:泛型方法+动态调用(零修改新增类型)
把公共处理逻辑抽成泛型方法,通过反射动态构造对应类型的泛型方法调用,后续新增类型不需要修改任何代码:
- 首先抽取公共泛型处理方法:
// 放在你当前的业务类中即可 private IEnumerable<SelectItem> BuildSelectList<T>(IList parentList) { return (parentList as IList<T>) .Select(item => new SelectItem { Value = item, Text = item.ToString() }) .OrderBy(selectItem => selectItem.Text); }
注:你原有代码中XYZ类型分支的Lambda表达式存在笔误,参数为x却使用了item变量,以上代码默认修正为直接取元素的ToString结果作为Text,你可以根据实际需求调整取值逻辑。
- 替换原有if-else分支为动态调用逻辑:
// 反射获取泛型方法,构造对应类型的实现并调用 var buildMethod = GetType() .GetMethod(nameof(BuildSelectList), System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) .MakeGenericMethod(parentPropertyAttribute.PropertyType); return buildMethod.Invoke(this, new object[] { parentList }) as IEnumerable<SelectItem>;
如果对性能有要求,可以加一层委托缓存,避免每次反射的开销:
// 业务类中加缓存字段 private readonly ConcurrentDictionary<Type, Func<IList, IEnumerable<SelectItem>>> _buildDelegateCache = new(); // 调用逻辑修改为从缓存取委托 private IEnumerable<SelectItem> GetSelectList(Type propertyType, IList parentList) { var buildDelegate = _buildDelegateCache.GetOrAdd(propertyType, type => { var method = GetType() .GetMethod(nameof(BuildSelectList), System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) .MakeGenericMethod(type); return Delegate.CreateDelegate(typeof(Func<IList, IEnumerable<SelectItem>>), this, method) as Func<IList, IEnumerable<SelectItem>>; }); return buildDelegate(parentList); }
缓存后性能和直接手写if-else分支几乎无差异。
方案2:类型-处理逻辑字典映射(支持自定义类型逻辑)
如果后续不同类型可能需要不同的Value/Text映射规则,可以用字典存储类型对应的处理委托,新增类型仅需要加一行字典配置:
- 业务类中定义映射字典:
private readonly Dictionary<Type, Func<IList, IEnumerable<SelectItem>>> _typeSelectBuilderMap = new() { [typeof(string)] = list => (list as IList<string>).Select(s => new SelectItem{ Value = s, Text = s }).OrderBy(i => i.Text), [typeof(XYZ)] = list => (list as IList<XYZ>).Select(x => new SelectItem{ Value = x.Id, Text = x.DisplayName }).OrderBy(i => i.Text) // 后续新增类型仅需要在这里加一行配置即可 };
- 替换if-else分支为字典取值:
if (_typeSelectBuilderMap.TryGetValue(parentPropertyAttribute.PropertyType, out var buildFunc)) { return buildFunc(parentList); } // 可加兜底逻辑,比如用方案1的反射逻辑处理未配置的类型 throw new NotSupportedException($"暂不支持类型 {parentPropertyAttribute.PropertyType.Name} 的下拉列表生成");
方案选型建议
- 如果所有类型的映射逻辑完全一致,优先选方案1,新增类型零代码修改
- 如果存在部分类型需要自定义映射规则,优先选方案2,维护清晰,扩展方便
内容的提问来源于stack exchange,提问作者Ms1
相关产品推荐
相关产品推荐

