C# LINQ需求实现演化

  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=},
new Book{Title="Book2", Author="Author2", ISBN="ISBN2", Price=},
new Book{Title="Book3", Author="Author3", ISBN="ISBN3", Price=},
new Book{Title="Book4", Author="Author4", ISBN="ISBN4", Price=}
}; IList<Book> results = new List<Book>();
foreach (Book book in books)
{
if (book.Price >= )
{
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 >= ;
} public static IList<Book> SearchBookByCondition(Condition condition)
{
IList<Book> books = new List<Book> {
new Book { Title = "Book1", Author = "Author1", ISBN = "ISBN1", Price = },
new Book { Title = "Book2", Author = "Author2", ISBN = "ISBN2", Price = },
new Book { Title = "Book3", Author = "Author3", ISBN = "ISBN3", Price = },
new Book { Title = "Book4", Author = "Author4", ISBN = "ISBN4", Price = }
}; 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
});
上一篇:C#执行oracle返回游标类型的存储过程


下一篇:fzu 2105 Digits Count ( 线段树 ) from 第三届福建省大学生程序设计竞赛