对于声明为: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. js 正则表达式 ( 1 )

    https://regexper.com/ 量词: ?: 最多一次(0次或者1次) +:至少一次(大于等于1次) *:大于等于0次 {n}:n次 {n,m}:n次到m次之间,包括n,m {n,}:n次 ...

  2. BZOJ1257 [CQOI2007]余数之和sum

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  3. centos 安装lnmp

    1:查看环境 cat /etc/redhat-release 2:关闭防火墙 chkconfig iptables off 3:配置CentOS 6.0 第三方yum源(CentOS默认的标准源里没有 ...

  4. 2016第七季极客大挑战Writeup

    第一次接触CTF,只会做杂项和一点点Web题--因为时间比较仓促,写的比较简略.以后再写下工具使用什么的. 纯新手,啥都不会.处于瑟瑟发抖的状态. 一.MISC 1.签到题 直接填入题目所给的SYC{ ...

  5. Github上的Watch和 Star的区别

    Github 推出了新的 Notification 系统,更改了原有的 Watch 机制,为代码库增加了 Star 操作.Notification 将接收 Watching 代码库的动态,包括:* I ...

  6. java 学习框架

    例如 Jsp.Velocity.Tiles.iText 和 POI.Spring MVC框架并不知道使用的视图,所以不会强迫您只使用 JSP 技术.

  7. [Android]学习笔记Activity_001

    操作button的说明 设置button的ID: android:id="@+id/button" 设置button的点击事件 findViewById(R.id.button). ...

  8. python 反射

    python 反射的核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动! 反射的四个基本函数使用 hasattr,getattr,setatt ...

  9. 最新 Eclipse IDE下的Spring框架配置及简单实例

    前段时间开始着手学习Spring框架,又是买书又是看视频找教程的,可是鲜有介绍如何配置Spring+Eclipse的方法,现在将我的成功经验分享给大家. 本文的一些源代码来源于码农教程:http:// ...

  10. javascript语言理解

    1.使用jquery remove,无法remove自身标签; 使用标签