深入理解 c# 第十章 使用Where方法的Lambda表示式去尋找奇數
阿新 • • 發佈:2019-02-20
class RangeFiltering { static void Main() { var collection = Enumerable.Range(0, 10) .Where(x => x % 2 != 0) .Reverse(); foreach (var element in collection) //collection 為System.Linq.Enumerable.ReverseIterator<int> //先foreach 後collection 後 in 後執行 x%2 != 0 //x為0 1 2 3 4 5 6 7 8 9 返回in //後var element 後 WriteLine 後 in //"var element"多次賦值 element 為 9 7 5 3 1 //之後執行 in, 退出迴圈 { Console.WriteLine(element); } } }
Where擴充套件方法對集合進行過濾的一種簡單但又十分強大的方式:它接受一個
謂詞,並將其應用於原始集合中的每個元素。Where同樣返回一個
IEnumerable<T>,但這一次結果集合中只包含與謂詞匹配的元素。
它先向整數集合應用奇偶過濾器,再對其進行反轉。
我們將方法呼叫連結到一起了。連結並不是一個新概念。
擴充套件方法允許將靜態方法呼叫連結到一起。這是擴充套件方法存在的主要原因之一。
強大的地方在於能夠以一種自然的方式將靜態方法連結起來。這正是.NET 3.5
的擴充套件方法主要出現在Enumerable和Queryable中的原因:LINQ針對資料
處理進行了專門的調整,將各個單獨的操作連結成一條管道,然後讓資訊在這個
管道中傳輸。
如果Reverse和Where不是擴充套件方法,那麼
一種方式是使用一個臨時變數,它能保持結構原封不動:
var collection = Enumerable.Range(0,10);
collection = Enumerable.Where(collection, x => x%2 != 0)
collection = Enumerable.Reverse(collection);
第二種保持"單語句"風格的方式,結果更糟
var collection = Enumerable.Reverse {Enumerable.Where {Enumerable.Range(0,10), x => x%2 != 0));
方法呼叫的順序看起來是反的,因為最裡面的方法呼叫(Range)會先執行,
然後再執行其他的,執行順序是從內向外的。儘管只有三個方法呼叫,但還是
異常醜陋。甚至比使用了更多操作符的查詢還要糟糕。
用了擴充套件方法感覺比較順眼
var collection = Enumerable.Range(0, 10)
.Where(x => x % 2 != 0)
.Reverse();
輸出
9
7
5
3
1