1. 程式人生 > >C#高階程式設計六十一天----LINQ中的擴充套件方法

C#高階程式設計六十一天----LINQ中的擴充套件方法

LINQ中的擴充套件方法

LINQwhere擴充套件方法,要想使用,必須匯入using System.Linq;我們看一下這個方法的宣告:

public static IEnumerable<TSource > Where<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate)

分析:返回型別是IEnumerable<TSource>

第一個引數:this IEnumerable<TSource> source代表的是他要擴充套件的型別

,也就是說在IEnumerable<TSource>可以直接呼叫where方法.

第二個引數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("使用LINQwhere方法:");

            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的定義,從函式簽名可以看出:擴張方法whereIEnumerable<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操作中,可以將各個單獨的操作連成一條管道,然後資訊在這條管道中傳輸.這其實是擴充套件方法存在的原因之一,因為擴充套件方法允許將靜態方法呼叫連線在一起.這樣做的好處是能夠以一種自然的方法將靜態方法連線起來.