Linq的Where是一个基于委托的代码封装,把数据筛选的通用逻辑完成,把判断逻辑交给委托传递。Select是基于委托的代码封装,把数据转换的通用逻辑完成,把转换逻辑交给委托传递。
Linq还有很多方法,这些方法大多都是基于委托的代码封装,也有一些是不需要委托的,例如Sum。
实现方法是把通用逻辑写好,把可变逻辑当成委托传递。
namespace MyStudy
{
public static class LinqExtension
{
/// <summary>
/// 与官方Where一样,迭代器返回Ienumerable,按需获取
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="tList"></param>
/// <param name="func"></param>
/// <returns></returns>
public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> tList, Func<T, bool> func) {
foreach (var t in tList) {
if (func.Invoke(t)) {
yield return t;
}
}
}
/// <summary>
/// 也能实现Where功能,一次性返回结果集
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="tList"></param>
/// <param name="func"></param>
/// <returns></returns>
public static List<T> MyWhereList<T>(this List<T> tList, Func<T, bool> func) {
List<T> result = new List<T>();
foreach (var t in tList) {
if (func.Invoke(t)) {
result.Add(t);
}
}
return result;
}
public static IEnumerable<T1> MySelect<T, T1>(this IEnumerable<T> tList, Func<T, T1> func) {
foreach (var t in tList) {
yield return func.Invoke(t);
}
}
}
}
代码中yield return是语法糖,返回Ienumerable结果集时,编译器会生成很多代码,是一个迭代器,能够实现数据按需加载。
Console测试运行代码
namespace MyStudy
{
class Program
{
static void Main(string[] args)
{
var testEntities = new List<TestEntity>() {
new TestEntity(){
Id = 1,
Name="Name1",
Age=18
},
new TestEntity(){
Id = 2,
Name="Name2",
Age=11
},
new TestEntity(){
Id = 3,
Name="Name3",
Age=19
}
};
var list1 = testEntities.MyWhere(x => x.Id > 1);
foreach (var item in list1) {
Console.WriteLine(item.Name);
}
var list2 = testEntities.Where(x => x.Id > 1);
foreach (var item in list1)
{
Console.WriteLine(item.Name);
}
var list3 = testEntities.MySelect(x => new { Id = x.Id, Name = x.Name });
foreach (var item in list3)
{
Console.WriteLine(item.Name);
}
var list4 = testEntities.Select(x => new { Id = x.Id, Name = x.Name });
foreach (var item in list4)
{
Console.WriteLine(item.Name);
}
//分解写法
Func<TestEntity, bool> func = new Func<TestEntity, bool>(t => t.Id > 1);
var list5 = testEntities.Where(func);
foreach (var item in list5)
{
Console.WriteLine(item.Name);
}
Console.ReadLine();
}
}
}
Linq to Object和Linq to Sql的区别:
Linq to Object 数据源是内存里的集合,传递的是委托。
Linq to Sql 数据源来自数据库,传递的是lanmbda表达式目录树(Expression<Func<TSource,bool>>),解析表达式转化成Sql语句。
2