简述LINQ的发展历程
LINQ:最終統(tǒng)治了所有的語言!
讓我們看看LINQ如何徹底改變了.NET中訪問數(shù)據(jù)的方式
.NET與其他技術(shù)棧的不同之處之一絕對是LINQ,它是Language Integrated Query的首字母縮寫。實(shí)際上,它是隨.NET Framework 3.5和Visual Studio 2008引入的,它是第一個(gè)獨(dú)立于體系結(jié)構(gòu)并集成在C#和Visual Basic語言中的框架。
借助LINQ,我們可以使用獨(dú)立于各種源的單個(gè)編程模型來查詢和操作數(shù)據(jù)。為了更好地理解它是什么,我們必須一步步的看下他的發(fā)展歷程。
在C#的第一個(gè)版本中,我們必須使用for或foreach循環(huán)來遍歷一個(gè)集合,正如我們所知,該集合實(shí)現(xiàn)IEnumerable接口,例如,在其中找到一個(gè)特定的對象。以下代碼返回公司年齡在19至36歲(20至35歲)之間的所有客戶:
class Customer { public int CustomerID { get; set; } public String CustomerName { get; set; } public int Age { get; set; } } class Program { static void Main(string[] args) { Customer[] customerArray = { new Customer() { CustomerID = 1, CustomerName = "Joy", Age = 22 }, new Customer() { CustomerID = 2, CustomerName = "Bob", Age = 45 }, new Customer() { CustomerID = 3, CustomerName = "Curt", Age = 25 },};Customer[] customers = new Customer[10]; int i = 0; foreach (Customer cst in customerArray) { if (cst.Age > 19 && cst.Age < 36) { customers[i] = cst; i++; }} } }有什么不同的方法?讓我們嘗試從“委托”的概念開始逐步進(jìn)行開發(fā)。delegate和返回的類型的方法的引用類型。它“委托”它旨在執(zhí)行代碼的方法,我們可以用這種方式聲明它:
public delegate bool Operations(int number);此委托可以指向所有接受輸入整數(shù)并返回布爾值的方法。例如,假設(shè)在CustomerOperations類中有一個(gè)方法:
public bool CustomerAgeRangeCheck(int number) {return number > 19 && number < 36; }我們可以注冊一個(gè)或多個(gè)將在執(zhí)行委托時(shí)執(zhí)行的方法:
Operations op = new Operations(CustomerOperations.CustomerAgeRangeCheck);或者簡單地:
Operations op = CustomerOperations.CustomerAgeRangeCheck;因此,我們可以使用委托,在這種情況下,它將返回true:
op(22);委托用于將方法作為參數(shù)傳遞給其他方法:事件處理程序和回調(diào)是通過委托調(diào)用的方法的示例。
C#2.0引入了匿名委托,您現(xiàn)在可以使用匿名方法來聲明和初始化委托。例如,我們可以這樣寫:
delegate bool CustomerFilters(Customer customer);class CustomerOperations {public static Customer[] FindWhere(Customer[] customers, CustomerFilters customerFiltersDelegate){int i = 0;Customer[] result = new Customer[6];foreach (Customer customer in customers)if (customerFiltersDelegate(customer)){result[i] = customer;i++;}return result;} }class Program {static void Main(string[] args){Customer[] customers = {new Customer() { CustomerID = 1, CustomerName = "Joy", Age = 22 },new Customer() { CustomerID = 2, CustomerName = "Bob", Age = 45 },new Customer() { CustomerID = 3, CustomerName = "Curt", Age = 25 },};Customer[] filteredCustomersAge = CustomerOperations.FindWhere(customers, delegate (Customer customer) //Using anonimous delegate{return customer.Age > 19 && customer.Age < 36;});} }使用C#2.0,我們的優(yōu)勢是可以使用匿名委托在不同條件下進(jìn)行搜索,而無需使用for或foreach循環(huán)。例如,我們可以使用上一個(gè)示例中相同的委托函數(shù)來查找“ CustomerID”為3或名稱為“ Bob”的客戶:
Customer[] filteredCustomersId = CustomerOperations.FindWhere(customers, delegate (Customer customer) {return customer.CustomerID == 3;});Customer[] filteredCustomersName = CustomerOperations.FindWhere(customers, delegate (Customer customer) {return customer.CustomerName == "Bob";});隨著C#的發(fā)展,從3.x版本開始,Microsoft團(tuán)隊(duì)引入了新功能,使代碼更加緊湊和易讀。這些直接支持LINQ來查詢不同類型的數(shù)據(jù)源并獲得產(chǎn)生單個(gè)指令的元素。
這些功能是:
-在VAR結(jié)構(gòu),一個(gè)隱式類型的局部變量。它是強(qiáng)類型化的,因?yàn)橐呀?jīng)聲明了類型本身,但是由編譯器根據(jù)分配給它的值使用類型推斷來確定類型。以下兩個(gè)語句在功能上等效:
var customerAge = 30; // Implicitly typed. int customerAge = 30; // Explicitly typed.-使用對象初始化程序,您可以在對象創(chuàng)建期間將值分配給對象的全部或某些屬性,而無需在分配指令行之后調(diào)用構(gòu)造函數(shù)。
Customer customer = new Customer { Age = 30, CustomerName = "Adolfo" };與以下代碼不同,在前一種情況下,所有內(nèi)容都被視為單個(gè)操作。
Customer customer = new Customer(); customer.Age = 30; customer.CustomerName = "Adolfo";匿名類型,由編譯器構(gòu)建的只讀類型,只有編譯器知道它。但是,如果程序集中的兩個(gè)或多個(gè)匿名對象初始化程序具有相同順序的屬性序列,并且具有相同的名稱和類型,則編譯器會(huì)將這些對象視為相同類型的實(shí)例。
匿名類型是將查詢結(jié)果中的一組屬性臨時(shí)分組的好方法,而不必定義單獨(dú)的命名類型。?
-擴(kuò)展方法,使您可以將方法“添加”到現(xiàn)有類型,而無需創(chuàng)建新的派生類型,重新編譯或修改原始類型。擴(kuò)展方法是靜態(tài)方法,但由于引入了語法糖,因此被稱為,因?yàn)樗鼈兪菙U(kuò)展類型上的實(shí)例方法。
public static class StringExtensionMethods {public static string ReverseString(this string input){if (string.IsNullOrEmpty(input)) return "";return new string(input.ToCharArray().Reverse().ToArray());} }擴(kuò)展方法必須在靜態(tài)類中定義。第一個(gè)參數(shù)表示要擴(kuò)展的類型,并且必須以關(guān)鍵字this開頭,其他參數(shù)則不需要它。
Console.WriteLine("Hello".ReverseString()); //olleH請注意,在方法調(diào)用中不得指定第一個(gè)參數(shù),該參數(shù)以this修飾符開頭。
Lambda表達(dá)式,可作為可變的或作為在一方法調(diào)用中的參數(shù)被傳遞匿名函數(shù)。
customer => customer.Age > 19 && customer.Age < 36;=>運(yùn)算符稱為lambda運(yùn)算符,而customer是函數(shù)的輸入?yún)?shù)。lambda運(yùn)算符右側(cè)的部分代表函數(shù)的主體及其返回的值,在這種情況下為布爾值。
在LINQ的引入中,我們終于有了C#3.5版本。
簡而言之,我們可以說LINQ是IEnumerable?和IQueryable?接口的擴(kuò)展方法庫,它使我們能夠執(zhí)行各種操作,如過濾,進(jìn)行投影,聚合和排序。
我們有幾種可用的LINQ實(shí)現(xiàn):
?LINQ到對象(內(nèi)存中對象集合)?LINQ到實(shí)體(實(shí)體框架)?LINQ to SQL(SQL數(shù)據(jù)庫)?LINQ to XML(XML文檔)?LINQ到數(shù)據(jù)集(ADO.Net數(shù)據(jù)集)?通過實(shí)現(xiàn)IQueryable接口(其他數(shù)據(jù)源)
在前面的示例中,數(shù)組用作數(shù)據(jù)源,因此隱式支持通用接口IEnumerable <T <。支持IEnumerable或其派生接口的類型(例如通用IQueryable?接口)稱為可查詢類型,使我們可以直接執(zhí)行LINQ查詢。如果數(shù)據(jù)源尚未以可查詢類型存儲(chǔ)在內(nèi)存中,則LINQ提供程序必須將其表示為可查詢類型。
正如我們所說,LINQ查詢主要基于.NET Framework 2.0版中引入的通用類型。這意味著,例如,如果嘗試將Customer對象添加到List對象,則在編譯時(shí)將生成錯(cuò)誤。使用通用集合很容易,因?yàn)椴恍枰谶\(yùn)行時(shí)強(qiáng)制轉(zhuǎn)換類型。
如果愿意,可以使用前面提到的var關(guān)鍵字來避免通用語法,在下面的示例中,該關(guān)鍵字要求編譯器通過檢查from子句中指定的數(shù)據(jù)源來推斷查詢變量的類型。
因此,讓我們看看如何能達(dá)到同樣的效果,在前面的代碼中我們獲得了使用匿名委托,使用LINQ到對象查詢,該變種構(gòu)造和lambda表達(dá)式:
這種語法稱為方法語法。
在下一個(gè)示例中,我們將使用查詢語法(Query Syntax),該語法是為那些已經(jīng)了解SQL語言并且因此會(huì)喜歡這種方法的人引入的:
查詢語法和方法語法在語義上是相同的,許多人發(fā)現(xiàn)查詢的語法更簡單,更易于閱讀 在查詢語法中,LINQ查詢運(yùn)算符在編譯時(shí)轉(zhuǎn)換為對相關(guān)LINQ擴(kuò)展方法的調(diào)用。
總結(jié)
以上是生活随笔為你收集整理的简述LINQ的发展历程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Visual Studio 2022发布
- 下一篇: 微服务组件记事本:Skywalking执