对于声明为: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. 人脸识别引擎SeetaFace编译 ubuntu

    00.SeetaFace简介 SeetaFace Engine is an open source C++ face recognition engine, which can run on CPU ...

  2. pecl 轻松安装php扩展

    PECL 的全称是 The PHP Extension Community Library ,是一个开放的并通过 PEAR(PHP Extension and Application Reposito ...

  3. strncpy函数使用

    strncpy()函数原型:extern char *strncpy(char *dest, char *src, int n);    用法:#include <string.h>    ...

  4. [转]mysql 视图

    转载自http://blog.csdn.net/evankaka/article/details/47071133 一. 视图概述 视图是一个虚拟表,其内容由查询定义.带来许多好处: 1. 视图能简化 ...

  5. .Net 高效开发之不可错过的实用工具

    Visual Studio Visual Studio Productivity Power tool: VS 专业版的效率工具. Web Essentials: 提高开发效率,能够有效的帮助开发人员 ...

  6. PHP常用函数总结

    数学函数 abs() 求绝对值 传一个数字 会返回该值的绝对值 例如:abs(-1);//输出1 ceil() 进一法取整数 返回不小于 value 的下一个整数,value 如果有小数部分则进一位. ...

  7. git误删文件找回方法/git版本回退方法

    使用git命令 git rm css/\*.css 我删掉了css文件夹下所有以.css结尾的文件,那么要怎样才能把文件找回来呢,下面说说方法,删掉其他的文件也是一样的方式找回. 第一步:使用git ...

  8. win10 64位专业版系统中显示32位dcom组件配置的方法

    word.excel是32位的组件,当用户64位系统在运行窗口中输入dcomcnfg命令时,在打开的组件服务管理窗口,是找不到Microsoft Excel.word程序的.另外,Windows 环境 ...

  9. 记录vmware虚拟机安装的时候一些注意

    1.选择从哪里安装操作系统的时候,要选择第三项过一会安装,不要选择第一项. 2.点击开始三角形的时候,选择中文安装或者英文安装,但键盘布局要选择USA,美国. 3.安装vmwaretools的时候,执 ...

  10. 分分钟教你从根本上认识Struts2框架

    在了解Struts2之前我们先来聊聊Struts1,我们都知道在很长的一段时间内,所有的MVC框架中,Struts1他是处于一个超级大咖的地位,无论是从市场角度和使用的用户的数量这个角度而言,Stru ...