Linq SelectionMany用法
来源:互联网 发布:linux samba配置步骤 编辑:程序博客网 时间:2024/05/16 10:16
学习Linq其实已经很久了,但是一直没有使用的习惯,故水平也始终没有提高。近来刻意强迫自己用Linq来替代C# 2.0的一些写法。这里有一些心得和各位分享一下。
首先看下面两个类的定义:
class Student { public int Score { get; set; } public Student(int score) { this.Score = score; } } class Teacher { public string Name { get; set; } public List<Student> Students; public Teacher(string order,List<Student> students) { this.Name = order; this.Students = students; } }
用以上两个类构建集合如下
List<Teacher> teachers = new List<Teacher> { new Teacher("a",new List<Student>{ new Student(100),new Student(90),new Student(30) }), new Teacher("b",new List<Student>{ new Student(100),new Student(90),new Student(60) }), new Teacher("c",new List<Student>{ new Student(100),new Student(90),new Student(40) }), new Teacher("d",new List<Student>{ new Student(100),new Student(90),new Student(60) }), new Teacher("e",new List<Student>{ new Student(100),new Student(90),new Student(50) }), new Teacher("f",new List<Student>{ new Student(100),new Student(90),new Student(60) }), new Teacher("g",new List<Student>{ new Student(100),new Student(90),new Student(60) }) };
这里有7个老师,每个人有3个学生,总共21一个学生里又有3个倒霉蛋没考及格……我们想要获得这3个倒霉蛋的集合。C# 2.0的代码如下:
List<Student> studentList = new List<Student>();
foreach (var t in teachers)
{
foreach (var s in t.Students)
{
if (s.Score < 60)
{
studentList.Add(s);
}
}
}
已经写了N多这样的二重foreach,写的都要吐了,简直恨不得做成代码段。因为所有编程语言都能这么写,有人觉得C#简单,可好学了,抓到就写,民工专用,抄袭Java,微软出品,必属垃圾,明天正午12点之前就会被淘汰……
反正我觉得C# 3.0之后是越来越难,越来越复杂。难道是年纪大了智商堪忧……那既然要反驳,今天我们就换个C# 3.0的新写法。首先是查询表达式的写法:
var list1 = from t in teachers from s in t.Students where s.Score < 60 select s;
是不是感觉好多了,就跟写SQL一样顺畅。而且一目了然。也许习惯于OOXX的.NET程序员不那么喜欢SQL的语法,那还可以试试Lamda表达式的写法:
var list2 = teachers.SelectMany(t => t.Students).Where(s => s.Score < 60);
嗯?怎么只有一行,这是不是太欺负人了,到时候公司数代码行数算工钱的时候怎么办……嗯……这种公司你还是离了吧……
写到这里我不禁感慨起SelectMany的伟大了,太好用了。其实我们刚才只是用了最简单的SelectMany也就是这个方法:
public static IEnumerable<TResult> SelectMany<TSource, TResult>( this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
这个用于IEnumerable<T>的扩展方法接受一个Func委托,根据你的需要再返回另一个IEnumerable<T>,配合Where真是秒杀二重foreach啊。
有时候我们需要输出更复杂的结果集,比如校长想知道教出这3个考不及格的倒霉蛋的,到底是哪几个更加倒霉的老师。那我们就要用到SelectMany的另一个重载方法了:
public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>( this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
第一眼看上去有点晕,重点是第一个Func委托的返回值IEnumerable<TCollection>,会遍历作为第二个Func委托的参数TCollection传递,供你构建所需要的投影集合。这里给出一个例子,下面的代码选出了门下有不及格学生的倒霉蛋老师+门生的分数:
var list3 = teachers.SelectMany( t => t.Students, (t, s) => new { t.Name, s.Score }) .Where(n => n.Score < 60);
在这里,校长大人得到的集合,不仅包含了所有不及格的分数,同时还对应了该分数学生的教师姓名。惨啊……
- Linq SelectionMany用法
- linq用法
- linq用法
- LINQ 用法集锦一
- C# LINQ的用法
- Linq中的高级用法
- Linq Distinct()用法
- Linq简单用法
- 常用Linq语句用法
- C## LinQ用法
- Sql,linq.lambada用法
- LINQ用法学习
- Linq 基本用法
- Linq之GroupBy用法
- linq lambda 用法,查询
- 常用Linq语句用法
- LinQ to SQL 用法
- C# LINQ基本用法(2) ---LINQ 数组
- jQuery 遍历
- CALayer4-自定义层
- 易解自定义view
- 用户10秒就关闭网站的25种原因
- Eclipse显示空格,Tab,回车和行号
- Linq SelectionMany用法
- 计算机科学相关刊物
- C++读写二进制文件块
- Emoji表情符号兼容方案
- Ubuntu13.10安装jdk1.7.0步骤
- Settings模块分析(一)
- 17周项目一(2)
- linux中SUID,SGID和SBIT的奇妙用途
- ping: unknown host解决办法