基础知识:
IDictionary<TKey, TValue>
延伸IEnumerable<T>
public interface IDictionary<TKey, TValue>: ..,
IEnumerable<KeyValuePair<TKey, TValue>>
{
...
}
Enumerable
类提供了提供 where
实现的扩展方法LINQ 中的子句
public static class Enumerable
{
...
public static IEnumerable<T> Where(this IEnumerable<T>,
bool Func<T> predicate)
{
...
}
}
使用 LINQ 时,编译器将查询语法转换为对 Enumerable.Where
的调用方法。
当 IEnumerable<T>
迭代此方法返回的谓词是对集合中的每个 项求值。
对应的item被yield到result。
这样的请求:
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。
最佳答案
不,您没有遗漏任何东西。 LINQ 唯一的键控系列知道的是 Lookup<TKey, TElement>
class ,即便如此,它也没有做任何特别的事情,它只是归结为 Lookup<TKey, TElement>
的事实工具 IEnumerable<IGrouping<TKey, TElement>>
;所以实际上,您正在遍历 IGrouping<TKey, TElement>
interface实现。
也就是说,除了 IEnumerable<T>
interface 之外,LINQ 没有任何关于接口(interface)的特殊知识。 ;恰好 IDictionary<TKey, TValue>
interface延伸IEnumerable<KeyValuePair<TKey, TValue>>
,这就是您首先可以对其执行操作的原因。
但是,对于具有特定查找机制的任何类型,您需要嗅探类型(这在 LINQ 中经常完成),然后尽可能调用特定于类型的操作。如果类型嗅探失败,你可以求助于与 IEnumerable<T>
一起工作的实现。 .
就像你在这里所做的那样。
关于c# - 优化Linq Where,使用key,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13730516/