上一篇說了from in select的本質,具體參見你所不知道的linq。本篇說下from...in... from... in... select 首先上一段代碼,猜猜結果是什麼? 這段代碼的運行結果是什麼呢? 答案是,這段代碼會報錯,根本編譯不過~~~~~~那麼按照上一篇,我們對TestApp ...
上一篇說了from in select的本質,具體參見你所不知道的linq。本篇說下from...in... from... in... select
首先上一段代碼,猜猜結果是什麼?
class Program { static void Main(string[] args) { /*var result = from s in new TestApp() { A = 2 } select s;*/ var result1 = from s in new TestApp() { A = 2 } from i in (s + 2).ToString() select (Convert.ToInt32(i) + s).ToString(); Console.WriteLine(result1.GetType() + " " + result1); Console.ReadLine(); } } public class TestApp { public int A { get; set; } }
這段代碼的運行結果是什麼呢?
答案是,這段代碼會報錯,根本編譯不過~~~~~~那麼按照上一篇,我們對TestApp進行方法擴展呢?那擴展Select擴展方法,發現依舊編譯不過。最後查linq的api,發現了一個叫SelectMany的方法。在結合SelectMany的用法我們可以猜測應該是這個擴展方法。於是我對TestApp進行瞭如下擴展,
public static class SelectExtension { public static string Select(this TestApp app, Func<int, int> selector) { return "hello,你是" + selector(app.A).ToString(); } public static string SelectMany(this TestApp app, Func<int, string> fun1, Func<int, string, string> fun2) { var j = fun1(app.A); return "hello,你真是" + fun2(app.A, j); } }
編譯,運行,結果如下:
那麼最後我們需要猜測SelectMany的通用方法是什麼,也就是SelectMany到底是怎麼定義的呢?
public static T SelectMany<T1,T2,T3,T>(this TestApp app, Func<T1, T2> fun1, Func<T1, T2, T3> fun2){}
其對應的from...in... from... in...select 語句如下
from t1 in TestApp
from t2 in fun1(t1)
select fun2(t1,t2)
- 對於需要擴展的類型也就是TestApp,位於第一個in後面
- t1,類型為T1的,它是fun1和func2的參數,具體t1是什麼,需要看SelectMany裡面如何實現
- t2,類型是T2的,它是通過fun1執行出來的,並且作為fun2的參數,不t2可能與t1沒有直接關係,這個看fun1如何定義
- 需要註意的是select後面的對象只是fun2的返回值,不是from...in... from... in...select語句的返回值,該語句的返回值是SelectMany擴展方法的返回值。
經過驗證發現推論是那麼完美,只要擴展SelectMany方法,代碼完美運行。
不過悲劇也發生了,from...in... from... in... from... in... select,三重迴圈該如何重載呢還是SelectMany方法嗎?我完全找不到北了,編譯不成功,擴展失敗,這是一個悲劇,希望知道的人告訴我結果~~~~~~~