C#高階程式設計六十一天----LINQ中的擴充套件方法
LINQ中的擴充套件方法
LINQ中where擴充套件方法,要想使用,必須匯入using System.Linq;我們看一下這個方法的宣告:
public static IEnumerable<TSource > Where<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate)
分析:返回型別是IEnumerable<TSource>
第一個引數:this IEnumerable<TSource> source代表的是他要擴充套件的型別
第二個引數Func<TSource,bool> predicate是一個委託,下面看一下他的宣告:
public delegate TResult Func<T,TResult>(T arg)封裝一個帶有T型別,返回TResult型別的方法.
下面我們使用LINQ中的where方法來檢索我們的列表.
案例如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace ConsoleApplication19
{
class Program
{
static void Main(string[] args)
{
List<Person> lists = new List<Person>();
lists.Add(new Person("zhangsan", 22));
lists.Add(new Person("lisi", 22));
lists.Add(new Person("wangwu", 20));
lists.Add(new Person("zhaoliu", 33));
lists.Add(new Person("zhouqi", 29));
IEnumerable<Person> reList = lists.Where<Person>
(param => param.Age >= 25 && param.Age <= 30);
foreach (var item in reList)
{
Console.WriteLine(item.Name+"====="+item.Age);
}
//其實LINQ一般的查詢,是可以直接寫where select等語句來實現,系統編譯時,會自動的將它
//轉換成擴張方法的呼叫.
var query =from r in lists where r.Age>=20&&r.Age<=30 select r ;
Console.WriteLine("使用LINQ的where方法:");
var result = query.OrderBy(x => x.Age);//使用OrderBy進行排序
foreach (var item in result)
{
Console.WriteLine(item.Name+"====="+item.Age);
}
//LINQ語句必須是以from開頭,以select或者group結尾
//注意:query變數,只是指定了一個查詢方式,並沒有執行
//真正執行的其實是在foreach時才產生的
//推遲查詢的執行
//推遲查詢的執行也就是說查詢實在迭代時才執行的,不是 var query中,案例:
Console.WriteLine("增加新內容後的輸出: ");
//新增加一個人,姓名是haha,年齡是22,28歲,這個新增加的人是符合年齡判斷條件的
lists.Add(new Person("haha",28));
foreach (Person per in query)
{
Console.WriteLine(per.Name + " " + per.Age);
}
//可以看出,第二次迭代完全可以接觸到物件,而我們並沒有定義新的query,這就是推遲執行
Console.ReadKey();
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
}
其實第一個擴充套件方法已經完成,就是使用where方法來篩選資料.
說明:在VS中,我們能看到where的定義,從函式簽名可以看出:擴張方法where從IEnumerable<TSource>型別的source中篩選出滿足條件的predicate的結果,返回值仍為IEnumerable<TSource>型別
案例:用select進行投影操作.
上例也已經體現,這裡不在多說了.
要不最後在說一下,免得你覺得我忽悠你:
where的用法:var query = lists.Where(it=>it.Age>=25)
select的用法:var query = from r in lists where r.Age >= 25 && r.Age < 30 select r;
說明:使用select方法後,產生了新的結果序列,該結果包含name以及age欄位.where方法以及select方法的區別還是很明顯的,where方法根據條件堆積和進行篩選操作,而select方法對集合進行投影操作得到新的結果序列.
檢視擴充套件方法Select的定義,得到其函式簽名如下:
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
從函式簽名中可以進一步瞭解到Select子句的作用:該擴充套件方法從集合source中按照selector指定的規則進行投影操作得到新的集合。
案例:用OrderBy進行排序,上例也有,仔細看
說明:
在本例中,使用OrderBy方法進行排序,該方法的函式簽名如下:
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
通過前面例子的解析,相信這個函式前面大家可以看懂了吧。這裡就不贅述了。
總結:
通過前面的三個方法的例子學習,可以發現,在LINQ操作中,可以將各個單獨的操作連成一條管道,然後資訊在這條管道中傳輸.這其實是擴充套件方法存在的原因之一,因為擴充套件方法允許將靜態方法呼叫連線在一起.這樣做的好處是能夠以一種自然的方法將靜態方法連線起來.