為了理解為什么我們應(yīng)該使用LINQ,讓我們看一些示例。假設(shè)您要從一系列Student對象中查找青少年學(xué)生的列表。
在C#2.0之前,我們必須使用“ foreach”或“ for”循環(huán)遍歷集合以查找特定對象。例如,我們必須編寫以下代碼,以從年齡在12至20歲(青少年13至19歲)的一系列學(xué)生中查找所有學(xué)生對象:
class Student { public int StudentID { get; set; } public String StudentName { get; set; } public int Age { get; set; } } class Program { static void Main(string[] args) { Student[] studentArray = { new Student() { StudentID = 1, StudentName = "John", Age = 18 }, new Student() { StudentID = 2, StudentName = "Steve", Age = 21 }, new Student() { StudentID = 3, StudentName = "Bill", Age = 25 }, new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 }, new Student() { StudentID = 5, StudentName = "Ron" , Age = 31 }, new Student() { StudentID = 6, StudentName = "Chris", Age = 17 }, new Student() { StudentID = 7, StudentName = "Rob",Age = 19 }, }; Student[] students = new Student[10]; int i = 0; foreach (Student std in studentArray) { if (std.Age > 12 && std.Age < 20) { students[i] = std; i++; } } } }
for循環(huán)的使用很麻煩,不可維護和可讀性差。C#2.0引入了委托,可以用來處理這種情況,如下所示。
示例:使用委托從C#2.0中的集合中查找元素
delegate bool FindStudent(Student std); class StudentExtension { public static Student[] where(Student[] stdArray, FindStudent del) { int i=0; Student[] result = new Student[10]; foreach (Student std in stdArray) if (del(std)) { result[i] = std; i++; } return result; } } class Program { static void Main(string[] args) { Student[] studentArray = { new Student() { StudentID = 1, StudentName = "John", Age = 18 } , new Student() { StudentID = 2, StudentName = "Steve", Age = 21 } , new Student() { StudentID = 3, StudentName = "Bill", Age = 25 } , new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } , new Student() { StudentID = 5, StudentName = "Ron" , Age = 31 } , new Student() { StudentID = 6, StudentName = "Chris", Age = 17 } , new Student() { StudentID = 7, StudentName = "Rob",Age = 19 } , }; Student[] students = StudentExtension.where(studentArray, delegate(Student std){ return std.Age > 12 && std.Age < 20; }); } } }
因此,使用C#2.0,您可以利用委托的優(yōu)勢找到符合任何條件的學(xué)生。你不必使用for循環(huán)來查找使用不同標(biāo)準(zhǔn)的學(xué)生。例如,可以使用相同的委托函數(shù)查找StudentId為5或姓名為Bill的學(xué)生,如下所示:
Student[] students = StudentExtension.where(studentArray, delegate(Student std) { return std.StudentID == 5; }); //此外,請使用同一委托使用其他條件 Student[] students = StudentExtension.where(studentArray, delegate(Student std) { return std.StudentName == "Bill"; });
C#團隊認(rèn)為他們?nèi)匀恍枰勾a更加緊湊和易讀。 因此,他們在C#3.0中引入了擴展方法,lambda表達(dá)式,表達(dá)式樹,匿名類型和查詢表達(dá)式。 您可以使用C#3.0的這些功能(它們是LINQ的構(gòu)建塊)來查詢不同類型的集合并在單個語句中獲取結(jié)果元素。
下面的示例演示如何使用帶有 lambda 表達(dá)式的 LINQ 查詢從 student 集合中查找特定的學(xué)生。
class Program { static void Main(string[] args) { Student[] studentArray = { new Student() { StudentID = 1, StudentName = "John", age = 18 } , new Student() { StudentID = 2, StudentName = "Steve", age = 21 } , new Student() { StudentID = 3, StudentName = "Bill", age = 25 } , new Student() { StudentID = 4, StudentName = "Ram" , age = 20 } , new Student() { StudentID = 5, StudentName = "Ron" , age = 31 } , new Student() { StudentID = 6, StudentName = "Chris", age = 17 } , new Student() { StudentID = 7, StudentName = "Rob",age = 19 } , }; // 使用LINQ查找青少年學(xué)生 Student[] teenAgerStudents = studentArray.Where(s => s.age > 12 && s.age < 20).ToArray(); // 使用LINQ查找名字為Bill的第一位學(xué)生 Student bill = studentArray.Where(s => s.StudentName == "Bill").FirstOrDefault(); // 使用LINQ查找StudentID為5的學(xué)生 Student student5 = studentArray.Where(s => s.StudentID == 5).FirstOrDefault(); } }
如上例所示,我們在單個語句中使用LINQ運算符和lambda表達(dá)式指定了不同的條件。因此,LINQ使代碼更緊湊和可讀性強,并且還可以用于查詢不同的數(shù)據(jù)源。例如,如果您在數(shù)據(jù)庫中有一個學(xué)生表,而不是上面的學(xué)生對象數(shù)組,則仍可以使用相同的查詢使用實體框架查找學(xué)生。
Familiar language(熟悉的語言): 開發(fā)人員不必為每種類型的數(shù)據(jù)源或數(shù)據(jù)格式學(xué)習(xí)新的查詢語言。
Less coding(更少的代碼): 與更傳統(tǒng)的方法相比,它減少了要編寫的代碼量。
Readable code(代碼可讀性): LINQ使代碼更具可讀性,因此其他開發(fā)人員可以輕松地理解和維護它。
Standardized way of querying multiple data sources(查詢多個數(shù)據(jù)源的標(biāo)準(zhǔn)化方法): 相同的LINQ語法可用于查詢多個數(shù)據(jù)源。
Compile time safety of queries(查詢的編譯時安全性): 它在編譯時提供對象的類型檢查。
IntelliSense Support(智能感知支持): LINQ為通用集合提供了IntelliSense。
Shaping data(數(shù)據(jù)形狀): 您可以以不同形狀檢索數(shù)據(jù)。