对于声明为:public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector);而言,调用它的形式就是: AList.SelectMany(itm=>itm.listProp);  // 其中AList中的属性里有 也是集合的 属性listProp。listProp集合元素类型是TResult。

对于 AList.Select(itm=>itm.listProp)返回的是 IEnumerable<List<TResult>>

现在对于声明为:public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector);

// TResult 中的字段 可以由 TSource和TCollection一起构成,当然也可以只 由TCollection的某些字段单独构成。

// 可以 假设:Class中有GradeId和ClassId字段和 List<Student> studs,而Student只有ClassId没有GradeId;那么

// IEnumerable<TSource>就是 Class的集合。 而 IEnumerable<TCollection>就是 Class中 Student的集合。

// 这时候调用 SelectMany的形式就是 classes.SelectMany(class=>class.studs,(class,stud)=>new{GradeId=class.GradeId,StudentId=stud.StudentId,...});

// 其中 classes就是 source, stud则是 studs中的元素。且如果方法中出现了两个委托参数,一般而言第二个委托需要间接用到第一个委托的返回值。

// 这个例子就说明了,为什么第二个委托里需要传 class。

      // 调用的时候是 source.SelectMany(i=>i.listProp,(i,s)=>...); i就是下面的itm
       // TSource就类似Class;TCollection就类似 Student; TResult则是 第二个委托的返回值的 类型,可以是匿名类型
public IEnumerable<TResult> SelectMany<TSource,TCollection,TResult>(source,collectionSelector,resultSelector)
{
IEnumerable<TResult> listResult = new IEnumerable<TResult>();
         // source就类似上面的 classes
foreach(var itm in source)
{
// collectionSelector(itm)返回的是 itm.listProp;
// itm.listProp的类型 就是 TCollection 类型。
IEnumerable<TCollection> blockCollection = collectionSelector(itm); // blockCollection类似某class 的studs
// 如果没有后面的 resultSelector那么这时候实际上会执行 listResult.AddRange(blockList); // IEnumerable<TResult> blockResult=new List<TResult>
foreach(var citm in blockCollection)// 类似上面的studs
{
// 这里之所以用到 itm 是因为 TResult 中的字段未必都是 citm 里进行了删减,而还包括一些扩增,扩增的
// 字段就可以是 itm中的。 举个栗子: itm是 Trade(有多个Order,即是 blockCollection),而 citm则是 Order,
// 那么这时候返回的 Result未必 是 Order的属性缩减后得到的新的 对象,还可以是 itm中除了 blockCollection属性外的
// 其它属性,例如收货人姓名 和 Order中的属性进行拼接。(注意,Order之前是没有收货人姓名的,因为一个 Order必然是
// 属于一个具体的 Trade,而一个Trade是由一个 买家购买物品产生的,故只需要在 Trade中有收件人姓名即可。这里我们
// 将收件人姓名这个属性 整合到了 Order中形成 'Order ,即 TResult。
// 所以说,之前觉得 itm是没必要的是因为自己没有搞懂 这个SelectMany的功能。总以为 对一个结构进行修改形成新的
// 结构只是说 对原来的结构进行 修剪, 现在才知道,实际上还可以 对原来的结构进行 增加,而用什么增加,既可以是
// 无关的数据,也可以是该结构的上级的数据。
listResult.Add(resultSelection(itm, citm)); // resultSelection(itm,citm)的返回值就是 TResult 对象
}
}
return listResult;
}

C#Linq技术中SelectMany(...)的内部实现推测的更多相关文章

  1. C#Linq技术中SelectMany(...)函数的内部实现的伪代码

    我们先来假设这种场景: 一个学校中有多个年级,一个年级有多个班级,一个班级里有多个学生.这里我们只需要班级.年级.和学生这三个概念: 让我们先来定义Class类和Student类: // 注意,Cla ...

  2. 在LINQ查询中LINQ之Group By的用法

    LINQ定义了大约40个查询操作符,如select.from.in.where.group 以及order by,借助于LINQ技术,我们可以使用一种类似SQL的语法来查询任何形式的数据.Linq有很 ...

  3. 编写高质量代码改善C#程序的157个建议——建议29:区别LINQ查询中的IEnumerable<T>和IQueryable<T>

    建议29:区别LINQ查询中的IEnumerable<T>和IQueryable<T> LINQ查询一共提供了两类扩展方法,在System.Linq命名空间下,有两个静态类:E ...

  4. LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别

    LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别 在写LINQ语句的时候,往往会看到.AsEnumerable() 和 .AsQueryable() .例如: s ...

  5. (转) Web 建站技术中,HTML、HTML5、XHTML、CSS、SQL、JavaScript、PHP、ASP.NET、Web Services 是什么?

    Web 建站技术中,HTML.HTML5.XHTML.CSS.SQL.JavaScript.PHP.ASP.NET.Web Services 是什么? 建站有很多技术,如 HTML.HTML5.XHT ...

  6. 在Activity中响应ListView内部按钮的点击事件

    最近交流群里面有人问到一个问题:如何在Activity中响应ListView内部按钮的点击事件,不要在Adapter中响应? 对于这个问题,我最初给他的解答是,在Adapter中定义一个回调接口,在A ...

  7. JavaScript文件中调用AngularJS内部方法或改变$scope变量

    需要在其他JavaScript文件中调用AngularJS内部方法或改变$scope变量,同时还要保持双向数据绑定: 首先获取AngularJS application: 方法一:通过controll ...

  8. ASP.NET MVC 解决LINQ表达式中的SqlMethods 未找到命名空间问题

    右键项目属性下的引用: 添加引用: 搜索寻找——System.Data.Linq,然后添加成功,即可解决LINQ表达式中的SqlMethods 未找到命名空间问题

  9. 在Activity中响应ListView内部按钮的点击事件的两种方法!!!

    在Activity中响应ListView内部按钮的点击事件的两种方法 转载:http://www.cnblogs.com/ivan-xu/p/4124967.html 最近交流群里面有人问到一个问题: ...

随机推荐

  1. div+css:div中图片垂直居中

    div中图片垂直居中 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &l ...

  2. matlab 曲线拟合

    曲线拟合(转载:http://blog.sina.com.cn/s/blog_8e1548b80101c9iu.html) 补:拟合多项式输出为str 1.poly2str([p],'x') 2. f ...

  3. idea maven scala

    http://docs.scala-lang.org/tutorials/scala-with-maven.html https://github.com/davidB/scala-archetype ...

  4. new bird in github

    首次使用先要建立本地github信息: git config - -global user.name  newbird git config - -global user.email   newbir ...

  5. Nginx笔记

    基础篇 关于Nginx Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.最早由俄罗斯的程序设计师Igor Sysoev所开发,并在一个BSD-like ...

  6. PHPCMS调用点击量的方法

    具体方法: 首先:需要在show.html 模板中首先加载jquery.min.js 这个js 其次:需要在要显示点击次数的位置写入: <span>点击:<span id=" ...

  7. vs2015 生成项目时,提示执行失败,参数错误

    今天vs2015 生成项目时,提示执行失败,参数错误.查了很多资料未解决 后来,发现只有一个项目出现这个问题,其他项目生成正常.怀疑是该项目解决方案的问题 于是将解决项目中的项目移除,逐一生成引用,解 ...

  8. Quartz 学习记录1

    原因 公司有一些批量定时任务可能需要在夜间执行,用的是quartz和spring batch两个框架.quartz是个定时任务框架,spring batch是个批处理框架. 虽然我自己的小玩意儿平时不 ...

  9. Androidstudio预览时出现错误java.lang.NoClassDefFoundError: com/android/util/PropertiesMap

    参考博客;http://blog.csdn.net/daqi1983/article/details/51474588 更改对应版本的SDK即可.

  10. Shell脚本学习第二课·

    Shell文件包含 shell也可以包含外部脚本,语法格式如下: . filename 或 source filename 例如创建两个shell脚本. 脚本1:test1.sh url = &quo ...