1. 程式人生 > 其它 >.Net【基礎回顧】泛型逆變協變和Linq

.Net【基礎回顧】泛型逆變協變和Linq

泛型

Generic

允許您延遲編寫類或方法中的程式設計元素的資料型別的規範,直到實際在程式中使用它的時候。

逆變與協變

協變就是父類轉變為子類,逆變就是子類轉變為父類。

通過在泛型引數上使用inout關鍵字,可以得到逆變或協變的能力

  • in 逆變

  • out 協變

IEnumerable<out T> //介面     
Action<in T> //委託
Func<out TResult> //委託
IReadOnlyList<out T> //介面
IReadOnlyCollection<out T> //介面

Linq


using System.Linq;
AsEnumerable()
  1. 判斷
Any()

All()
  1. 篩選

Where()

Select()

SelectMany()

List<Bouquet> bouquets = new List<Bouquet>() 
{
  new Bouquet { Flowers = new List<string> { "sunflower", "daisy", "daffodil", "larkspur" }},
  new Bouquet{ Flowers = new List<string> { "tulip", "rose", "orchid" }},
  new Bouquet{ Flowers = new List<string> { "gladiolis", "lily", "snapdragon", "aster", "protea" }},
  new Bouquet{ Flowers = new List<string> { "larkspur", "lilac", "iris", "dahlia" }}
};

// *********** Select ***********            
IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers);

// ********* SelectMany *********
IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers);

  1. 排序
OrderBy()

OrderByDescending()

ThenBy()

ThenByDescending()

Reverse()

  1. 連線
Join()  // 對應sql中的inner join

GroupJoin() //對應sql中的left join

var sg = db.Users.Join(db.Departments, u => u.DepartmentId, d => d.DepartmentId, (u,d) => new { u, d }).Select(o=>o).ToList();

//注意:這裡將只顯示使用者裡DepartmentId和部門表裡DepartmentId相等的資訊,如果使用者沒有部門ID則此條使用者資訊不會顯示

var sg = db.Users.GroupJoin(db.Departments, u => u.DepartmentId, d => d.DepartmentId, (u,d) => new { u, d }).Select(o=>o).ToList();

// 注意:上面將返回所用使用者資訊和對應的部門資訊(即使用者部門ID資訊缺少,那麼使用者列表也會顯示)
  1. 分組聚合
GroupBy()

Sum() 

Max() 

Min() 

Average() 

Count 

longCount 
  1. 集合運算
Contact() //兩個集合合併成一個新的集合

Union() //並集 去重的

Except() //差集計算 list去除共同部分

Intersect() //交集計算 注意判斷元素相等

  1. 序列運算
First()  //找不到會丟擲異常

FirstOrDefault() //找不到返回NULL

 

Last()

LastOrDefault()

 

ElementAt()

ElementAtOrDefault()

 

Take()

TakeWhile()  //一直提取到條件為止,條件之後的資料不再抽出

public void TakeWhileTest()
{
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
 
    //在這裡需要注意.使用TakeWhile獲取小於6的元素,是從第一個元素開始,
    //一直到不滿足其小於6這個條件為止.也就是執行到和9這個元素比較後,就結束比較了
    //可以想象一下執行過程.
    //5<6=true;4<6=true;1<6=true;3<6=true
    //9<6=false;   這裡就停止繼續比較了 
    var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);
 
    Console.WriteLine("First numbers less than 6:");
 
    foreach (var n in firstNumbersLessThan6)
    {
        Console.WriteLine(n);
    }
}
 
//結果
// 5
// 4
// 1
// 3

Skip()

SkipWhile()  //從不符合條件的資料開始取當前和之後所有資料

public void SkipWhileTest()
{
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
 
    //這裡和TakeWhiel又有些不一樣。
    var allButFirst3Numbers = numbers.SkipWhile(n => n < 6);
 
    Console.WriteLine("結果:");
    foreach (var n in allButFirst3Numbers)
    {
        Console.WriteLine(n);
    }
 
}
 
//結果
// 9
// 8
// 6
// 7
// 2
// 0
  1. 型別轉換
ToArray()

ToDictionary()

ToList()

ToLookUp()

  1. 累加函式 Aggregate
static void Main()
    {
        int[] array = { 1, 2, 3, 4, 5 };
        int result = array.Aggregate((a, b) => b + a);//累加
                                                      // 1 + 2 = 3
                                                      // 3 + 3 = 6
                                                      // 6 + 4 = 10
                                                      // 10 + 5 = 15
        Console.WriteLine(result);

        result = array.Aggregate((a, b) => b * a);//階乘
                                                  // 1 * 2 = 2
                                                  // 2 * 3 = 6
                                                  // 6 * 4 = 24
                                                  // 24 * 5 = 120
        Console.WriteLine(result);
    }


    //輸出結果: 

    //15 

    //120