SelectMany用于将集合的集合扁平化为单层集合,支持投影、过滤与关联操作。例如,从学生列表中提取所有课程:var allCourses = students.SelectMany(s => s.Courses); 可保留上下文信息,如学生姓名与序号:.SelectMany((s, i) => s.Courses.Select(c => new { StudentName = s.Name, Course = c, Order = i })); 能替代嵌套循环,实现声明式数据处理,链式调用Where、OrderBy等方法筛选并排序课程:.Where(c => c.Contains("数")).OrderBy(c => c); 还可模拟内连接,结合Join完成订单与商品的关联查询,是处理层级结构如树形、用户角色等场景的核心工具。

SelectMany 的核心作用是把“集合中的集合”变成一个单层的集合,也就是常说的扁平化(Flattening)。它不只适用于简单嵌套,还能配合投影、过滤和关联逻辑使用,是处理层级数据结构(比如树形、订单+商品、用户+角色等)时非常实用的操作符。
基础扁平化:把 List> 变成 List
这是最直观的用途。比如你有一组学生,每个学生有多个课程,你想得到所有课程的列表:
var students = new[]
{
new Student { Name = "张三", Courses = new[] { "数学", "英语" } },
new Student { Name = "李四", Courses = new[] { "物理", "化学", "生物" } }
};
var allCourses = students.SelectMany(s => s.Courses);
// 结果:{"数学", "英语", "物理", "化学", "生物"}
登录后复制
这里 s => s.Courses 是一个“选择子集合”的函数,SelectMany 会自动遍历每个学生,并把他们的 Courses 合并成一个序列。
带索引或额外信息的投影
有时你不仅需要扁平后的元素,还想保留外层上下文,比如知道某个课程属于哪个学生。SelectMany 重载支持传入带索引的 selector,或者用更灵活的二元 lambda:
- 用
(student, index)获取学生本身和位置 - 返回匿名类型或新对象,把内外信息组合起来
var coursesWithStudent = students
.SelectMany(
(s, i) => s.Courses.Select(c => new { StudentName = s.Name, Course = c, Order = i })
);
登录后复制
结果每项都包含学生名、课程名和该学生在原数组中的序号。
替代多层 foreach,简化嵌套查询逻辑
传统写法要两层循环才能拿到所有“学生-课程”对,而 SelectMany 让这种关联变得声明式且可链式调用:
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~