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