.Net【基礎回顧】泛型逆變協變和Linq
阿新 • • 發佈:2022-12-02
泛型
Generic
允許您延遲編寫類或方法中的程式設計元素的資料型別的規範,直到實際在程式中使用它的時候。
逆變與協變
協變就是父類轉變為子類,逆變就是子類轉變為父類。
通過在泛型引數上使用in
或out
關鍵字,可以得到逆變或協變的能力
-
in
逆變 -
out
協變
IEnumerable<out T> //介面
Action<in T> //委託
Func<out TResult> //委託
IReadOnlyList<out T> //介面
IReadOnlyCollection<out T> //介面
Linq
using System.Linq; AsEnumerable()
- 判斷
Any()
All()
- 篩選
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);
- 排序
OrderBy()
OrderByDescending()
ThenBy()
ThenByDescending()
Reverse()
- 連線
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資訊缺少,那麼使用者列表也會顯示)
- 分組聚合
GroupBy()
Sum()
Max()
Min()
Average()
Count
longCount
- 集合運算
Contact() //兩個集合合併成一個新的集合
Union() //並集 去重的
Except() //差集計算 list去除共同部分
Intersect() //交集計算 注意判斷元素相等
- 序列運算
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
- 型別轉換
ToArray()
ToDictionary()
ToList()
ToLookUp()
- 累加函式 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