【发布时间】:2012-12-05 19:01:36
【问题描述】:
基础知识:
IDictionary<TKey, TValue> 扩展 IEnumerable<T>
public interface IDictionary<TKey, TValue>: ..,
IEnumerable<KeyValuePair<TKey, TValue>>
{
...
}
Enumerable 类提供了在 LINQ 中实现 where 子句的扩展方法
public static class Enumerable
{
...
public static IEnumerable<T> Where(this IEnumerable<T>,
bool Func<T> predicate)
{
...
}
}
使用 LINQ 时,编译器会将查询语法转换为对 Enumerable.Where 方法的调用。
当迭代从此方法返回的IEnumerable<T> 时,谓词对集合中的每个 项进行评估。
对应的项目产生结果。
所以这样的请求:
var l_res = from n in List where n.key == 1 select n;
将遍历List 中的每个项目。
如果List 实现IDictionary<TKey, TValue>,并且where 子句位于字典中用作键的属性上,我如何利用该键来避免遍历每条记录并执行查找?
我已经知道我可以测试IEnumerable<T> 是否也是IDictionary<TKey, TValue> 实现,然后选择最好使用的请求:
if(list is IDictionary<int, T>)
{
var l_res = ((IDictionary<int, T>) list)[1];
}
else
{
var l_res = from n in List where n.key == 1 select n ;
}
但我想知道我是否遗漏了 LINQ 中存在的处理此类键控集合的内容。
注意:LINQ-to0SQL 提供程序使用IQueryable<T> 和表达式树来做同样的事情,但我的问题是关于 LINQ-to-Objects。
【问题讨论】:
-
你不使用
var l_res = ((IDictionary)list)[1];的原因是什么? -
这真的是您的应用程序的性能问题还是您在进行微优化?
-
好吧,完全没有理由。我正在通过 .Net MicroFramework 编写 OData Provider。并希望避免使用 IQueryable 导致表达式树的巨大复杂性。然后我想确保在走得更远之前不会错过任何东西......
标签: c# linq c#-4.0 linq-to-objects