如何根据ItemType返回Join所需outerKeySelector委托优化LINQ代码?
根据ItemType返回LINQ Join的outerKeySelector委托以精简重复代码
完全可以通过绑定枚举与委托的方式消除GetResult中的重复逻辑,核心思路是把ItemType枚举值和对应的outerKeySelector委托做映射,然后统一复用Join逻辑。
方法一:字典映射(推荐,性能更优)
定义类级别的静态只读字典,提前完成枚举与委托的绑定,后续调用直接取值:
// 仅初始化一次的静态映射字典 private static readonly Dictionary<ItemType, Func<ItemModel, long>> _itemKeyMap = new() { { ItemType.Item1, item => item.ItemId1 }, { ItemType.Item2, item => item.ItemId2 }, { ItemType.Item3, item => item.ItemId3 }, { ItemType.Item4, item => item.ItemId4 } }; private static IEnumerable<IdModel> GetResult(IEnumerable<ItemModel> itemList, IEnumerable<IdModel> idList, ItemType itemType) { if (!_itemKeyMap.TryGetValue(itemType, out var outerKeySelector)) { throw new ArgumentOutOfRangeException(nameof(itemType), "无效的ItemType枚举值"); } // 统一执行Join逻辑,彻底消除重复代码 return itemList.Join( idList, outerKeySelector, idItem => idItem.Id, (_, matchedIdItem) => new IdModel { Id = matchedIdItem.Id, Quantity = matchedIdItem.Quantity }); }
方法二:单独的委托获取方法
如果觉得字典不够直观,也可以写一个专门返回委托的方法:
private static Func<ItemModel, long> GetOuterKeySelector(ItemType itemType) { return itemType switch { ItemType.Item1 => i => i.ItemId1, ItemType.Item2 => i => i.ItemId2, ItemType.Item3 => i => i.ItemId3, ItemType.Item4 => i => i.ItemId4, _ => throw new ArgumentOutOfRangeException(nameof(itemType)) }; } private static IEnumerable<IdModel> GetResult(IEnumerable<ItemModel> itemList, IEnumerable<IdModel> idList, ItemType itemType) { var outerKeySelector = GetOuterKeySelector(itemType); return itemList.Join( idList, outerKeySelector, j => j.Id, (_, j) => new IdModel { Id = j.Id, Quantity = j.Quantity }); }
优化说明
- 两种方式都彻底消除了
GetResult中的重复Join逻辑,后续新增ItemType时,仅需在映射字典或switch分支中添加一行即可,符合开闭原则。 - 字典映射方式仅初始化一次,后续调用直接取值,性能更优;switch方式代码更直白,适合枚举数量较少的场景。
内容的提问来源于stack exchange,提问作者A1exZr
相关产品推荐
相关产品推荐

