Linq是C#3.0引入的,在C#2.0實現從集合中過濾符合條件的記錄實現方式。
假設有一個Book類,以及一個Book類的集合,現在需要從集合中查詢出單價大於50的Book。
1、固定查詢欄位的實現方式:
Book.cs類:
using System; using System.Collections.Generic; using System.Text; namespace LINQTest { public class Book { public string Title { get; set; } public decimal Price { get; set; } public string Author { get; set; } public string ISBN { get; set; } } }
Help.cs類:
using System; using System.Collections.Generic; using System.Text; namespace LINQTest { public class Helper { public static IList<Book> SearchBookByPrice() { IList<Book> books = new List<Book> { new Book{Title="Book1", Author="Author1", ISBN="ISBN1", Price=30}, new Book{Title="Book2", Author="Author2", ISBN="ISBN2", Price=40}, new Book{Title="Book3", Author="Author3", ISBN="ISBN3", Price=50}, new Book{Title="Book4", Author="Author4", ISBN="ISBN4", Price=60} }; IList<Book> results = new List<Book>(); foreach (Book book in books) { if (book.Price >= 50) { results.Add(book); } } return results; } } }
Program.cs類:
using System; using System.Collections.Generic; using System.Text; namespace LINQTest { class Program { static void Main(string[] args) { foreach (Book book in Helper.SearchBookByPrice()) { Console.WriteLine("{0}-{1}", book.Title, book.Price); } } } }
上面的程式碼中實現了根據Price查詢集合中大於50的記錄。但是當需求有變動,需要根據Title來查詢時,則上面的實現方法需要另外進行編寫按Title查詢的方法。
2、不固定查詢欄位的實現方式
查詢條件最後返回的只是true或false,在新定義的方法中,只要if語句中返回為true的記錄,新增到集合中即可,而不需要去知道具體是什麼查詢條件。
Helper.cs類:
using System; using System.Collections.Generic; using System.Text; namespace LINQTest { public class Helper { public delegate bool Condition(Book book); public bool ConditionTitle(Book book) { return book.Title == "Book2"; } public bool ConditionPrice(Book book) { return book.Price >= 50; } public static IList<Book> SearchBookByCondition(Condition condition) { IList<Book> books = new List<Book> { new Book { Title = "Book1", Author = "Author1", ISBN = "ISBN1", Price = 30 }, new Book { Title = "Book2", Author = "Author2", ISBN = "ISBN2", Price = 40 }, new Book { Title = "Book3", Author = "Author3", ISBN = "ISBN3", Price = 50 }, new Book { Title = "Book4", Author = "Author4", ISBN = "ISBN4", Price = 60 } }; IList<Book> results = new List<Book>(); foreach (Book book in books) { if (condition(book)) { results.Add(book); } } return results; } } }
Program.cs類:
using System; using System.Collections.Generic; using System.Text; namespace LINQTest { class Program { static void Main(string[] args) { //Helper.Condition condition = new Helper.Condition(new Helper().ConditionTitle); Helper.Condition condition = new Helper().ConditionTitle; foreach (Book book in Helper.SearchBookByCondition(condition)) { Console.WriteLine("{0}-{1}", book.Title, book.Price); } } } }
以上的實現方式採用委託delegate,在C#2.0中還提供了匿名方法,集合中過濾查詢條件的程式碼可修改為:
Helper.Condition condition = delegate(Book book) { return book.Title == "Book2"; };
IList<Book> results = Helper.SearchBookByCondition(delegate(Book book) { return book.Title == "Book2"; });
在C#3.0提供了Lambda表示式,則實現集合過濾方式為:
IList<Book> results = Helper.SearchBookByCondition(book => book.Title == "Book2");
但這樣實現每次都要帶類名Helper,我們希望IList自身就具有這個方法,C#3.0提供了擴充套件方法。
3、C#3.0擴充套件方法實現方式
public static class Helper { public delegate bool Condtion(Book book); public static IList<Book> Where(this IList<Book> books, Condtion condition) { IList < Book > results = new List<Book>(); foreach (Book book in books) { if (condition(book)) { results.Add(book); } } return results; } }
IList<Book> results = books.Where(book => book.Title == "Book2");
5、IEnumberable實現方式
由於IList都繼承自IEnumberable,則可以通過擴充套件IEnumberable來實現。
public static class Helper { public delegate bool Condtion<T>(T t); public static IEnumerable<T> Where<T>(this IEnumerable<T> items, Condtion<T> condition) { foreach (T t in items) { if (condition(t)) { yield return t; } } } }
6、通用擴充套件類
using System; using System.Collections.Generic; using System.Text; namespace LINQTest { public class Extension { public delegate TResult Func<T, TResult>(T t); public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> filter) { foreach (T item in source) { if (filter(item)) { yield return item; } } } public static IEnumerable<TResult> Select<T, TResult>(this IEnumerable<T> source, Func<T, TResult> selector) { foreach (T item in source) { yield return selector(item); } } } }
var result = books.Where(book => book.Title == "Book2").Select(book => new { Key = book.Title,Value=book.Price });