C#9中用LINQ实现Dictionary拍平转字符串键值对列表的优雅写法探讨
适配C# 9的最优实现方案
你尝试的source.SelectMany((score, terms) => ...)编译失败的核心原因:C# 9 暂不支持在lambda参数位置直接解构可解构类型(该特性为C# 10引入),且SelectMany的遍历入参是单个KeyValuePair<int, List<string>>元素,并非元组类型,无法直接在lambda参数列表完成解构。
注:以下优化写法的运行时性能与你原有两种方案完全一致,无额外开销,仅做语法层面的简化。
方案1:LINQ查询语法(当前环境可读性最优)
查询语法原生支持对KeyValuePair的解构(依赖.NET Core 2.0+为KeyValuePair提供的Deconstruct扩展方法),无需冗余中间变量,写法接近自然语义:
var target = ( from (score, terms) in source from term in terms select KeyValuePair.Create(score.ToString(), term) ).ToList();
- 多层
from本身就是SelectMany的语法糖,解构逻辑直接内嵌在遍历声明中,无额外冗余代码 - 完全适配C# 9、.NET Core 5环境
方案2:优化后的方法链写法(偏好链式调用可选)
如果更习惯方法链风格,可以完全消除原方案2中的块级解构语句,用表达式体简化逻辑:
var target = source .SelectMany(kvp => kvp.Value.Select( term => KeyValuePair.Create(kvp.Key.ToString(), term) )) .ToList();
- 优化点:省去了
var(score, terms) = kvp的中间解构步骤,用KeyValuePair.Create静态方法替代显式new,编译器自动推断泛型参数,代码更简洁
方案3:C# 10+ 原生lambda解构(可选升级方向)
如果后续升级到C# 10及以上版本,就可以直接实现你最初尝试的lambda参数解构写法,完全无冗余代码:
// 仅适配C# 10及以上环境 var target = source .SelectMany((score, terms) => terms.Select( term => KeyValuePair.Create(score.ToString(), term) )) .ToList();
内容的提问来源于stack exchange,提问作者void.pointer
相关产品推荐
相关产品推荐

