对于声明为: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. OS命令注入中的空格

    1.bash 空格可以替换为%20.%09(tab).%2b(+) in url.{IFS} 2.Win shell 空格可以替换为%20.%09(tab).%0b.%0c.%2b(+) in url

  2. install hadoop on xubuntu

    0. install xubuntu we recommend to set username as "hadoop" after installation, set user & ...

  3. 字符串作为map的key

    #include <map> #include <string> struct cmp_str{ bool operator()(char const* a, char con ...

  4. mybatis- spring 批量实现数据导入数据库

    终于实现了ibatis的批量插入,此方法插入3000条数据,比单条插入可以节省一半的时间XML代码: <insert id="insertBatch" parameterTy ...

  5. 微软压力测试工具 web application stress

    转自 http://www.cnblogs.com/tonykan/p/3514749.html lbimba  铜牌会员 这里给广大的煤油推荐一个web网站压力测试工具.它可以用来模拟多个用户操作网 ...

  6. coreseek+sphinx+mysql+thinkphp整合

    1.安装coreseek 1.1首先升级或安装系统依赖库 yum install make gcc g++ automake libtool mysql-client libmysqlclient15 ...

  7. MySQL 子查询与连接操作笔记

    SQL语句之间是可以进行连接操作的,在一些复杂的数据操作中必须用到连接操作.简单的说就是一个SQL语句的结果可以作为相连接的SQL操作的一部分.SQL结构化查询语句,子查询是指的所有的SQL操作,并非 ...

  8. Visifire Chart相关属性详解

    <vc:Chart x:Name="HourlyChart" Theme="Theme1" Grid.Row="1" xmlns:vc ...

  9. 第3月第15天 afconvert lame

    1. //CAF 转换成MP3 (可以) afconvert -f mp4f -d aac -b 128000 /Users/amarishuyi/Desktop/sound1.caf/Users/a ...

  10. IOS中div contenteditable=true无法输入

    在IOS中<div contenteditable="true"></div>中点击时可以弹出键盘但是无法输入.加一个样式-webkit-user-sele ...