Jon*_*eet 12
你的意思是查询表达式,或者查询在幕后做什么?
查询表达式首先扩展为"普通"C#.例如:
var query = from x in source
where x.Name == "Fred"
select x.Age;
Run Code Online (Sandbox Code Playgroud)
被翻译成:
var query = source.Where(x => x.Name == "Fred")
.Select(x => x.Age);
Run Code Online (Sandbox Code Playgroud)
这个的确切含义取决于source当然的类型...在LINQ to Objects中,它通常实现IEnumerable<T>并且Enumerable扩展方法发挥作用......但它可以是一组不同的扩展方法.(例如,LINQ to SQL将使用Queryable扩展方法.)
现在,假设我们正在使用LINQ to Objects ...在扩展方法扩展之后,上面的代码变为:
var query = Enumerable.Select(Enumerable.Where(source, x => x.Name == "Fred"),
x => x.Age);
Run Code Online (Sandbox Code Playgroud)
接下来实现Select并Where变得重要.离开了错误检查,他们的东西是这样的:
public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
Func<T, bool> predicate)
{
foreach (T element in source)
{
if (predicate(element))
{
yield return element;
}
}
}
public static IEnumerable<TResult> Select<TSource, TResult>
(this IEnumerable<TSource> source,
Func<TSource, TResult> selector)
{
foreach (TSource element in source)
{
yield return selector(element);
}
}
Run Code Online (Sandbox Code Playgroud)
接下来是迭代器块扩展到状态机,我不会在这里讨论,但我有一篇文章.
最后,将lambda表达式转换为额外的方法+适当的委托实例创建(或表达式树,取决于所调用方法的签名).
所以基本上LINQ使用了很多 C#的聪明功能:
但是,单个操作非常简单 - 它们不执行索引等.连接和分组是使用哈希表完成的,但像"where"这样的简单查询只是线性的.不要忘记LINQ to Objects通常只将数据视为只能向前发送的序列 - 它不能像二进制搜索那样执行.
通常我希望手写查询比LINQ to Objects快一点,因为抽象层次较少,但它们的可读性较差,性能差异通常不会很大.
与性能问题一样:如有疑问,请测量!
| 归档时间: |
|
| 查看次数: |
510 次 |
| 最近记录: |