Linq To Objects是基于C#3.0的扩展方法特性和更复杂的类型参数推断特性。
扩展方法能像目标类型的实例方法一样被调用,而且也能像实例方法一样被链起来,而C#3.0中的类型推断允许基于一个类型参数推断结果来推断另外一个类型参数,如果没有这两个特性,那么linq to objects估计会是另外一个样子。
var result = from defect in SampleData.AllDefects select defect;
像这样的一个最简单linq表达式,C#编译器会先对表达式进行转译。
var result = SampleData.AllDefects.Select(defect => defect);
这就是转译之后的代码。Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)方法是定义在Enumerable类中的扩展方法。
在整个转译的过程中,仅仅只是把表达式翻译成普通的C#代码(将对应的linq操作符转换成对相应方法的调用)。转译完成之后,编译器再尝试推断类型参数,应用类型参数。所以说我们使用linq表达式和调用像“Select”这样的扩展方法而生成的IL代码是完全相同的。
var result = from defect in SampleData.AllDefects where defect.Status != Status.Closed where defect.AssignedTo == SampleData.Users.TesterTim select defect;
而linq to objects的延迟加载则是因为迭代器。整个表达式运行完成之后并不会把所有的数据都经过where条件过滤然后将所有符合条件的数据加到结果中,当我们使用foreach语句迭代结果的时候,一个数据项都会从数据源中流出,经过管道过滤,最终到达结果集中被使用。当然,如果使用类似于Count()这样的方法会造成所有的数据都被加载到结果集中(一般来说,返回另外一个序列的操作是延迟加载的,而返回单一值的会立即计算)。
以上是我个人的理解,如果有问题,欢迎大家指出。
近期Linq To Objects总结
时间: 2024-11-09 00:39:08