1. 程式人生 > 實用技巧 >LINQ之方法語法

LINQ之方法語法

上節講到使用linq的查詢關鍵字進行查詢,這節講一下linq查詢的另一種方式——linq方法。

使用linq方法語法,必須要會用lambda表示式,配合lambda表示式才能體會到linq的優雅便捷。

linq方法是一系列的擴充套件方法,對於實現了IEnumerable介面的物件,都可以使用,擴充套件方法在VS智慧提示中顯示為一個正方體加一個向下的虛箭頭。

對於上節的程式碼,使用方法語法則可以簡潔為一行:

 int[] vs = { 1, 6, 3, 2, 5 };
 var a = vs.Where(v => v > 3);
 foreach (var
t in a) { Console.Write(t); }

執行結果為:65
使用方法語法的好處是可以直接在原資料後操作,可以使用鏈式程式設計實現複雜的查詢操作。但是一些情況下查詢語法更好用,這個要看開發的需求以及個人喜好。

下面介紹一些常用的linq方法(以下例子基於上述vs陣列):

Select

linq方法基本上都要配合lambda表示式,因為linq方法的引數一般都是一個委託,而lambda表示式在填充委託方面有著優雅的特性(不熟悉lambda表示式用法的同學可以回顧往期文章:淺析C#中的Lambda表示式),表示式引數即是每個遍歷到的資料。Select()方法用於隱式迭代所有的資料,可以在迭代中對每個資料進行處理:

var a = vs.Select(v => ++v);//將所有資料加一併返回

SelectMany()方法用於返回多行結果,它可以在方法中巢狀查詢。

Skip,Take

Skip(int i)方法用於跳過前i個元素,相反的,Take(int i)方法用於獲取前i個元素

var a = vs.Skip(2);//執行結果:325
var a = vs.Take(2);//執行結果:16

SkipWhile()和TakeWhile()用於滿足條件即停止執行,前者返回剩下的元素,後者返回匹配到的元素,個人覺得這兩個方法執行邏輯很繞,有興趣的可以自己寫程式碼看看效果。
SkipLast(int i)和TaskLast(int i)用於跳過和獲取最後的元素。

Concat

concat(IEnumerator<T>)用於將引數拼接在原資料的後面。

var a = vs.Concat(new List<int>(){7,9,8});//執行結果16325798

Contains

Contains(T t)用於指定其引數是否包含在該資料來源中。

var a = vs.Contains(2);//true

它還有一個過載方法Contains(T t,IEqualityComparer<T> e),第二個引數用於自定義比較的規則,因為有的時候系統的直接比較法不是我們想要的,所以就需要我們自定義比較規則,這個可以展開來解釋一下:它的第二個引數是一個介面,接口裡邊定義了一個Equals()方法,我們需要自定義一個類實現這個介面,請看程式碼:

public class MyClass : IEqualityComparer<int>
{
    public bool Equals(int x, int y){
      y = y - 2;
      return x == y;
    }
    //該方法是此介面的另一個方法,與當前上下文無關,此處不做說明
    public int GetHashCode(int obj){
        throw new NotImplementedException();
     }
}

var a = vs.Contains(2, new MyClass());//false

x就是Contains()的第一個引數,y是迭代資料來源中的每一個數據,我現在將比較規則改為比較x是否等於y-2,相當於說讓比較2是否包含在{-1, 4, 1, 0, 3}中,顯然,結果為false。

一般情況下,自定義規則用在比較自定義物件陣列或集合中。

OrderBy

OrderBy()用於排序,根據lambda表示式的返回值進行升序排序,它有一個過載,用於自定義排序規則,用法跟Contains()類似。

var a = vs.OrderBy(c => c);//執行結果 12356

下面我使用它的過載降序排序資料

public class MyClass : IEqualityComparer<int>, IComparer<int>
{
  public int Compare(int x, int y){
    return -(x - y);
  }
}

再次呼叫後結果為降序:

var a = vs.OrderBy(c => c,new MyClass());//執行結果65321

其它

下面簡潔介紹一下另一些常用的方法(瞭解更多linq方法請查閱相關文件):

boolAll(),

boolAny()

前者所有元素滿足即為true,後者至少一個滿足即為true

intCount(),

longLongCount()

兩者都是計數,並且可以統計滿足條件元素個數,只是返回值不同

TMax(),

​TMin()

返回最大最小值,可以自定義排序規則(凡是涉及到比較或排序的,都可以自定義規則)
doubleSum() 求和

TElementAt(),

TElementAtOrDefault()

獲取指定位置上的元素,後者對於訪問出錯的情況下返回可以將設定的預設值返回

這是我的公眾號二維碼,獲取最新文章,請關注此號