概述
在.NET Framework 3.5中提供了LINQ 支持后,LINQ就以其强大 而优雅的编程方式赢得了开发人员的喜爱,而各种LINQ Provider更是满天飞, 如LINQ to NHibernate、LINQ to Google等,大有“一切皆LINQ”的 趋势。LINQ本身也提供了很好的扩展性,使得我们可以轻松的编写属于自己的 LINQ Provider。
本文为打造自己的LINQ Provider系列文章第二篇,主 要详细介绍自定义LINQ Provider中两个最重要的接口IQueryable和 IQueryProvider。
IEnumerable<T>接口
在上一篇打造自己 的LINQ Provider(上):Expression Tree揭秘》一文的最后,我说到了这样一 句话:需要注意的是LINQ to Objects并不需要任何特定的LINQ Provider,因为 它并不翻译为表达式目录树,带着这个问题,我们先来看下面这段代码,查询的 结果query为IEnumerable<String>类型:
static void Main(string[] args)
{
List<String> myList = new List<String>() { "a", "ab", "cd", "bd" };
IEnumerable<String> query = from s in myList
where s.StartsWith("a")
select s;
foreach (String s in query)
{
Console.WriteLine(s);
}
Console.Read ();
}
这里将返回两条结果,如下图所示:
这里就有一个问题,为什么在LINQ to Objects中返回的是 IEnumerable<T>类型的数据而不是IQueryable<T>呢?答案就在本 文的开始,在LINQ to Objects中查询表达式或者Lambda表达式并不翻译为表达 式目录树,因为LINQ to Objects查询的都是实现了IEnmerable<T>接口的 数据,所以查询表达式或者Lambda表达式都可以直接转换为.NET代码来执行,无 需再经过转换为表达式目录这一步,这也是LINQ to Objects比较特殊的地方, 它不需要特定的LINQ Provider。我们可以看一下IEnumerable<T>接口的 实现,它里面并没有Expression和Provider这样的属性,如下图所示: