亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

.Net如何實現LINQ~

2019-11-14 16:11:11
字體:
來源:轉載
供稿:網友

本文內容

  • 引入
  • 實現 LINQ 的兩個前提
    • 擴展方法
    • λ 表達式
  • LINQ
  • 參考資料

本文說明 LINQ 是如何實現的,知道這點,才能更好地使用它~

如果你剛接觸 LINQ,那么可能不會那么快就理解。因為,LINQ 涉及的技術比較多,可以說它是眾多技術的集大成者,因此使用 LINQ 需要你對幾個知識點有一定認識,包括泛型委托、擴展方法、匿名函數、λ 表達式(Lambda 表達式),在此基礎上,才可能靈活運用 LINQ。這也是為什么 LINQ 在 VS 2008 才出現,而不是之前。

最好是,先學習泛型委托,再通過學習 System.Array 類提高對匿名函數和 λ 表達式的理解。

下載 Demo

引入


如果有一個關于一級方程式賽車冠軍 Racer 的集合 ,Racer 包括賽車手的姓名、國家、冠軍次數等屬性,要想對這個集合操作,比如檢索、排序等等,在 C# 3.0 以前,我們要想知道 Brazil 這個國家的冠軍都有誰,并且按降序排序,代碼如下所示:

IEnumerable<Racer> brazilChampions = champions.Where(
   delegate(Racer r)
   {
       return r.Country == "Brazil";
   }).OrderByDescending(
   delegate(Racer r)
   {
       return r.Wins;
   }).Select(
   delegate(Racer r)
   {
       return r;
   });

其中,champions 是冠軍集合。

注意:whereOrderByDescending、Select 函數都把委托作為函數參數,鏈式調用最后會返回一個可用 foreach 語句迭代的 IEnumerable 可枚舉對象 brazilChampions。

雖然上面代碼看上去還可以,但是,有 delegate 關鍵字、有形式參數,還不夠簡潔。是否可以沒有這些啰嗦的東西呢?估計你也想到了——λ 表達式!代碼如下所示:

IEnumerable<Racer> brazilChampions = champions.
   Where(r => r.Country == "Brazil").
   OrderByDescending(r => r.Wins).
   Select(r => r);

嗯,簡潔多了~可我們又想了,既然是查詢,那能不能像數據庫查詢那樣寫個 SQL 語句呢?比如:select * from champions t where t.country="Brazil" orderby desc 或類似形式,SQL 中有謂詞~

當然有,這就是 LINQ~

但 LINQ 不是一下冒出來的,它有個過程,這也是為什么 LINQ 在 VS 2008 才出現,而不是之前。

了解如何實現 LINQ,才能更好地使用它~

 

實現 LINQ 的兩個前提


要想了解 LINQ 是如何實現的,需要知道兩個必要的技術點:擴展方法和 λ 表達式。當然,還涉及到泛型委托。

擴展方法

其實,擴展方法并不陌生,我第一次注意這個用法是在 Ext.Net,它的項目里有個工具類程序集。其中的字符串工具類 StringUtils ,如判斷字符串是否為“空”,無論是 null,還是長度為 0 都返回 true,從而擴展 .Net 的字符串操作。如下所示 StringUtils 工具類的代碼片段:

public static class StringUtils
{
    /// <summary>
    /// Determine is the string is null or empty.
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    public static bool IsEmpty(this string text)
    {
        return string.IsNullOrEmpty(text);
    }
    
    /// <summary>
    /// Determine is the string is NOT null or empty.
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    public static bool IsNotEmpty(this string text)
    {
        return !text.IsEmpty();
    } 
 
    ……
 
    /// <summary>
    /// 
    /// </summary>
    /// <param name="text"></param>
    /// <param name="pattern"></param>
    /// <returns></returns>
    public static bool Test(this string text, string pattern)
    {
        return Regex.IsMatch(text, pattern);
    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="text"></param>
    /// <param name="pattern"></param>
    /// <param name="options"></param>
    /// <returns></returns>
    public static bool Test(this string text, string pattern, RegexOptions options)
    {
        return Regex.IsMatch(text, pattern, options);
    }
 
    ……
    
 }

顯然,.Net 沒有對字符串提供 IsEmpty Test 方法(其實,.Net 提供了 string.IsNullOrEmpty 方法),但如果在你的程序集中定義了這個類,那么就能在你的代碼中對字符串用“.”直接調用這些方法,如 "helloworld".IsEmpty()。

注意,StringUtils 是靜態類。靜態類主要是為了共享,靜態類的成員也必須是靜態的。靜態類一般在程序加載的時候被構造。靜態類可以有構造函數,但只被調用一次。這樣,在你的代碼中就不需要實例化這個類,更重要的是,對函數參數 string 類型使用了 this 關鍵字。

因為,所有的泛型集合都繼承了 IEnumerable<T> 接口這樣,我們自定義過濾函數 Where,對 IEnumerable<T> 用擴展方法。如下所示,泛型集合根據指定條件返回符合條件的集合:

public static IEnumerable<T> Where(this IEnumerable<T> source, Func<T, bool> PRedicate)
{
    foreach (T item in source)
    {
        if (predicate(item))
            yield return item;
    }
}

其中,函數 Where 有兩個參數:一個是帶 thisIEnumerable<T>,另一個是 .net 提供的只有兩個輸入參數的帶返回值的泛型委托 Func<T, TResult>。這樣,對任何泛型集合調用 Where 方法都相當于:

champions.Where(Func<T, bool> predicate)

如:

IEnumerable<Racer> brazilChampions = champions.Where(
   delegate(Racer r)
   {
       return r.Country == "Brazil";
   });

既然自定義的泛型集合 Where 方法返回了 IEnumerable<T> 類型,我們當然可以再定義一個對泛型集合的排序函數,比如叫 OrderByDescending(this IEnumerable<T> source, Func<T, int> predicate)

因為自定義函數 Where 的返回類型,也是函數 OrderByDescending 的輸入類型,所以它們能形成一個調用鏈。

λ 表達式

C# 3.0 引入了一個新的語法——λ 表達式(Lambda 表達式)。λ 演算背后是有數學基礎的,也就是說,函數聲明,包括函數名、形參、返回類型等等都是可以沒有的,直接函數體。在對泛型集合調用上面自定義的 Where 函數時,就可以這樣寫:

IEnumerable<Racer> brazilChampions = champions.Where(r => r.Country == "Brazil");

其中,r 并沒有定義。這下代碼,簡潔多了。

前面說了擴展方法和 λ 表達式,現在離 LINQ 近了。

 

LINQ


我們希望 LINQ 跟 SQL 一樣,也有類 select、where、group by、order by 這些關鍵字,編譯器只要把這些關鍵字映射到相應的擴展方法上就行了。

而 LINQ 的關鍵字跟 SQL 很像,比如 from、where、orderby、descending 和 select 等。

上面的泛型查詢,改成 LINQ 如下所示:

var query = from r in champions
            where r.Country == "Brazil"
            orderby r.Wins descending
            select r;

其中,

  • 1,
where r.Country == "Brazil" 

轉換成

Where(r=>r.country=="Brazil");
  • 2,
orderby r.Wins descending

轉換成

OrderByDescending(r=>r.Wins)
  • 3,
select r

轉換成

Select()

LINQ 查詢必須以 from 子句開始,以 selectgroup 子句結束。在這兩個子句之間,可以使用 whereorderby、jion 和其他 from 子句。

LINQ 的具體用法你就得自己研究了,不在本文討論范圍內~

 

參考資料


  • .NET C# 聲明、實例化和使用委托以及委托在 C# 中的發展
  • 沒有 Lambda 演算何來匿名函數——匿名函數(匿名方法和 Lambda)、委托、LINQ
  • wiki λ演算
  • Database SQL Language Reference
  • .NET Framework System.Array.Sort 演示

 

下載 Demo


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕日韩欧美精品在线观看| 日韩第一页在线| 中文字幕亚洲综合久久筱田步美| 欧美电影在线观看完整版| 日韩欧美一区二区三区久久| 日韩精品视频免费专区在线播放| 欧美华人在线视频| 亚洲欧美精品中文字幕在线| 国产精品永久免费观看| 亚洲直播在线一区| 欧美一区在线直播| 国产精品久久久久久久久久99| 91av网站在线播放| 亚洲影院高清在线| 亚洲无限乱码一二三四麻| 久久99热精品这里久久精品| 欧美精品videosex性欧美| 日韩精品高清在线观看| 国产原创欧美精品| 亚洲第一区中文99精品| 丰满岳妇乱一区二区三区| 欧美日韩一二三四五区| 欧美色xxxx| 国产精品极品美女在线观看免费| 久久综合亚洲社区| 一区二区三区高清国产| 中文字幕少妇一区二区三区| 九九九热精品免费视频观看网站| 国产精品网红直播| 国产精品极品美女粉嫩高清在线| 成人欧美在线视频| 91麻豆桃色免费看| 中文.日本.精品| 国产91在线播放| 91国产精品视频在线| 欧美在线视频在线播放完整版免费观看| 欧美性videos高清精品| 国产热re99久久6国产精品| 午夜伦理精品一区| 国产va免费精品高清在线| 日韩高清中文字幕| 欧美在线视频免费观看| 亚洲欧美国产精品久久久久久久| 亚洲国产天堂久久综合| 欧美中文在线视频| 国产69久久精品成人| 97在线看免费观看视频在线观看| 国产色综合天天综合网| 一区二区欧美激情| 在线日韩日本国产亚洲| 国内精品一区二区三区四区| 国产精品福利片| 欧美黑人巨大精品一区二区| 狠狠操狠狠色综合网| 精品久久久久久久久久久久久| 国产精品视频1区| 久久久国产精品一区| 国产美女91呻吟求| 欧美多人爱爱视频网站| 91久久久国产精品| wwwwwwww亚洲| 日韩欧美在线视频日韩欧美在线视频| 欧美大人香蕉在线| 久久久久久网站| 一区二区三区视频在线| 亚洲福利在线播放| 国产精品视频区| 欧美肥老太性生活视频| 色综合久综合久久综合久鬼88| 7777免费精品视频| 欧美日韩亚洲天堂| 国产精品成人aaaaa网站| 日韩在线免费观看视频| 欧美在线不卡区| 日韩a**中文字幕| 自拍亚洲一区欧美另类| 亚洲最大成人网色| 中国china体内裑精亚洲片| 亚洲精品国偷自产在线99热| 成人a级免费视频| 久久久精品影院| 中文字幕v亚洲ⅴv天堂| 国产一区二区三区丝袜| 亚洲精品久久久久久久久久久久久| 欧美激情在线观看视频| 亚洲美女精品成人在线视频| 欧美成在线视频| 国产精品www网站| 北条麻妃99精品青青久久| 亚洲91精品在线| 亚洲人av在线影院| 成人在线国产精品| 久久99视频免费| 亚洲电影免费观看高清完整版| 国产精品免费一区豆花| 91精品在线观看视频| 亚洲午夜精品久久久久久久久久久久| 98精品在线视频| 国产精品久久久| 国产精品久久久久9999| 日韩av综合网| 国产999精品久久久影片官网| 亚洲精品久久7777777| 欧美大片在线看免费观看| 欧美日韩中国免费专区在线看| 国产乱肥老妇国产一区二| 一区二区亚洲欧洲国产日韩| 91产国在线观看动作片喷水| 亚洲高清福利视频| 亚洲国产婷婷香蕉久久久久久| 亚洲电影免费观看高清完整版在线观看| 色婷婷久久av| 久久久久久午夜| 久久久av亚洲男天堂| 久久久亚洲福利精品午夜| 欧美大肥婆大肥bbbbb| 91亚洲va在线va天堂va国| 亚洲人成电影在线| 国产噜噜噜噜久久久久久久久| 国产91在线播放精品91| 在线播放国产精品| 欧美日韩加勒比精品一区| 免费97视频在线精品国自产拍| 日韩av电影手机在线观看| 日韩免费观看av| 欧美体内谢she精2性欧美| 日韩成人在线电影网| 91国偷自产一区二区三区的观看方式| 久久精品99无色码中文字幕| 国产成人一区二区三区| 欧美成人在线免费视频| 午夜精品一区二区三区在线视| 2021久久精品国产99国产精品| 久久久精品久久| 亚洲少妇激情视频| 亚洲国产欧美一区二区丝袜黑人| 日韩亚洲综合在线| 日韩精品在线观看网站| 精品亚洲永久免费精品| 中文在线资源观看视频网站免费不卡| 亚洲精品在线91| 国产精品一区二区性色av| 国产日韩亚洲欧美| 午夜精品一区二区三区在线播放| 久久成人这里只有精品| 久久99热精品这里久久精品| 91久久精品国产91性色| 久久久亚洲福利精品午夜| 久久男人的天堂| 久久久亚洲国产| 蜜月aⅴ免费一区二区三区| 亚洲一二在线观看| 亲爱的老师9免费观看全集电视剧| 日本19禁啪啪免费观看www| 高清亚洲成在人网站天堂| 91精品视频免费| 日韩国产一区三区| 欧美激情性做爰免费视频| 国产精品美女www爽爽爽视频| 精品久久久久久久久久久久久久| 国产精品99久久久久久白浆小说| 日韩在线免费视频观看| 国产欧美精品一区二区三区介绍| 中文字幕在线观看日韩|