2022-09-13|閱讀時間 ‧ 約 11 分鐘

玩轉C#之【LINQ 基本介紹】

介紹

LINQ全名是(Language-Integrated Query),是一組以直接將查詢功能整合至C# 語言為基礎之技術的名稱。
大家可以想像SQL有SQL的查詢語法,MySql有MySql的查詢語法,但我們可以只透過LINQ語法,C#會自動幫我們轉換成對應的資料庫查詢語法,有點像是秦始皇統一文字的這種感覺。

歷史演進

C#1.0 1.1 時代 委派的做法
public class LambdaShow
{
   public delegate void NoReturnNoPara();//定義一個委派
   public delegate void NoReturnWthPara(int x,int y);//定義一個帶參數委派
   
   public voui Show()
   {
       NoReturnNoPara method = new NoReturnNoPara(this.Donothing);//實體化一個委派
   }

   private void DoNothing()
   {
       Console.WriteLine("Test");
   }
}
C# 2.0 時代 匿名方法
  • 除了可以少起方法名稱之外
  • 還可以讀取出K值
public voui Show()
{
   int k =1;
   NoReturnNoPara method = new NoReturnNoPara(delegate ()
   {
       Console.WriteLine(k);
       Console.WriteLine("Test");
   });
}
C# 3.0 時代 lambda
  • "=" 稱之為goes to
  • 左邊是參數列表,右邊是方法體,本質是一個方法
public voui Show()
{
   NoReturnNoPara method = new NoReturnNoPara( () =>
   {
       Console.WriteLine("Test");
   });
}
//帶參數
public voui Show()
{
   NoReturnWthPara method = new NoReturnWthPara( (int x,int y) =>
   {
       Console.WriteLine("Test");
   });
}
//也可以省略參數型別
public voui Show()
{
   NoReturnWthPara method = new NoReturnWthPara( (x,y) =>
   {
       Console.WriteLine("Test");
   });
}
//如果方法體只有一行 可以去掉{} 跟;
public voui Show()
{
   NoReturnWthPara method = new NoReturnWthPara( (x,y) => Console.WriteLine("Test"));
}
//new NoReturnWthPara() 也可以省略掉
public voui Show()
{
   NoReturnWthPara method = (x,y) => Console.WriteLine("Test");
}
lambda表達式 是個什麼呢?
  • 首先不是委派,委派是類型
  • 也不是委派的實例 因為這裡是省略new 委派()
  • 只是一個方法(作用是一個方法) = 不完全正確
  • 編譯之後實際上是一個類中類,裡面的一個internal 方法,然後被綁定到靜態的委派類型
透過IL反編譯一下

匿名類 var 擴展方法
普通的類別
Student student = new Student()
   {
       Id =1,
       Name = "大禹治水",
       Age = 25,
       ClassId= 2
   };
   student.Study();
匿名類別 C#3.0
object model = new
   {
       Id = 2,
       Name ="小帥哥",
       Age =25,
       ClassId= 2
   };
   Console.WriteLine(model.Id);//不能直接讀取Id 編譯器不允許通過
解決方式:
第一種
動態類型 C#4.0 =可以避開編譯器檢查
dynamic dModel =new
   {
       Id = 2,
       Name ="小帥哥",
       Age =25,
       ClassId= 2
   };
   Console.WriteLine(dModel.Id);
   dModel.Id =3;
第二種
用var C#3.0
實際上編譯後有一個真實的類別,從反編譯工具可以看出只有Get方法所以不能Set
var dModel =new
   {
       Id = 2,
       Name ="小帥哥",
       Age =25,
       ClassId= 2
   };
   Console.WriteLine(dModel.Id);
   dModel.Id =3;//不能執行  因為只能Get 不能Set
第三種
反射可以找到
var =是一個語法糖,由編譯器自動推算類型 var =宣告的時候就確定類型
var i1 =1;
   var s="123";
   s=123;//宣告的時候就確定類型
擴充方法 C#3.0
Student student = new Student()
   {
       Id =1,
       Name = "大禹治水",
       Age = 25,
       ClassId= 2
   };
   student.Study();
我們希望學生能有一個唱歌的功能,但不希望修改原本的類別,但是又要增加方法
首先要是一個靜態類別,裡面的一個靜態方法
public static class ExtenedMethod
{
   public static void Sing(Student student)
   {
       Console.WriteLine($"{student.Name} sing a Song");
   }
}
正常情況下使用方式
ExtendMethod.Sing(student);
如果我們在第一個參數前面加上一個this
public static class ExtenedMethod
{
   public static void Sing(this Student student)
   {
       Console.WriteLine($"{student.Name} sing a Song");
   }
}
可以變成這樣
student.Sing();
擴充方法就是在靜態類別,裡面的一個靜態方法,第一個參數前面加上一個this 用途:可以不修改類,增加方法也就是改變寫法方便了一點 缺點:優先調用類型的方法(有隱患), 擴充父類型,導致任何子類別都有這個方法,而且還有可能被覆蓋,最好指定類型擴充

Linq to object

一般情況過濾數據
var list = new List<Student>();
   foreach(var item in studentList)
   {
       if(item.Age < 30)
       {
           list.Add(item);
       }
   }
等價的做法
public static class ExtendMethod
{
   public static List<Student>EleventWhere(this Kust<Student> source,Func<Student,bool> func)
   {
        var list = new List<Student>();
       foreach(var item in source)
       {
           if(func.Invoke(item))
           {
               list.Add(item);
           }
       }
       
   }
}
var result = list.EleventWhere(x=>x.Age < 30);//陳述式語法

yield 跌代器

  1. 基於委派封裝解構,去掉重複代碼
  2. 泛型,應對個總類型情況
  3. 加上跌代器,延遲獲取
public static IEnumberable<T> ElevenWhere<T>(this IEnumberable<T> source,Func<T,bool> func)
{
   foreach(var item in source)
   {
       if(func.Invoke(item))
       {
           yield return item;
       }
   }
}

linq常用方法介紹

Where =篩選 Select=轉換 Min/Max/OrderBy/
Linq To Object(Enumerable) Linq To Sql(Queryable) =SQL+ADO.NET 表達式目錄樹解析SQL
下一章節會正式介紹LINQ的語法

參考資料

本篇已同步發表至個人部落格 https://moushih.com/2022ithome13/
我的鐵人賽文章
https://ithelp.ithome.com.tw/articles/10289873
分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.