C#Linq技術中SelectMany(...)的內部實現推測

來源:互聯網
上載者:User

標籤:

對於聲明為: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。

 1      // 調用的時候是 source.SelectMany(i=>i.listProp,(i,s)=>...); i就是下面的itm
       // TSource就類似Class;TCollection就類似 Student; TResult則是 第二個委託的傳回值的 類型,可以是匿名型別 2 public IEnumerable<TResult> SelectMany<TSource,TCollection,TResult>(source,collectionSelector,resultSelector) 3 { 4 IEnumerable<TResult> listResult = new IEnumerable<TResult>();
         // source就類似上面的 classes 5 foreach(var itm in source) 6 { 7 // collectionSelector(itm)返回的是 itm.listProp; 8 // itm.listProp的類型 就是 TCollection 類型。 9 IEnumerable<TCollection> blockCollection = collectionSelector(itm); // blockCollection類似某class 的studs10 // 如果沒有後面的 resultSelector那麼這時候實際上會執行 listResult.AddRange(blockList);11 12 // IEnumerable<TResult> blockResult=new List<TResult>13 foreach(var citm in blockCollection)// 類似上面的studs14 {15 // 這裡之所以用到 itm 是因為 TResult 中的欄位未必都是 citm 裡進行了刪減,而還包括一些擴增,擴增的16 // 欄位就可以是 itm中的。 舉個栗子: itm是 Trade(有多個Order,即是 blockCollection),而 citm則是 Order,17 // 那麼這時候返回的 Result未必 是 Order的屬性縮減後得到的新的 對象,還可以是 itm中除了 blockCollection屬性外的18 // 其它屬性,例如收貨人姓名 和 Order中的屬性進行拼接。(注意,Order之前是沒有收貨人姓名的,因為一個 Order必然是19 // 屬於一個具體的 Trade,而一個Trade是由一個 買家購買物品產生的,故只需要在 Trade中有收件者姓名即可。這裡我們20 // 將收件者姓名這個屬性 整合到了 Order中形成 ‘Order ,即 TResult。21 // 所以說,之前覺得 itm是沒必要的是因為自己沒有搞懂 這個SelectMany的功能。總以為 對一個結構進行修改形成新的22 // 結構只是說 對原來的結構進行 修剪, 現在才知道,實際上還可以 對原來的結構進行 增加,而用什麼增加,既可以是23 // 無關的資料,也可以是該結構的上級的資料。24 listResult.Add(resultSelection(itm, citm)); // resultSelection(itm,citm)的傳回值就是 TResult 對象25 }26 }27 return listResult;28 }

 

C#Linq技術中SelectMany(...)的內部實現推測

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.