Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用密钥优化Linq Where_C#_Linq_C# 4.0_Linq To Objects - Fatal编程技术网

C# 使用密钥优化Linq Where

C# 使用密钥优化Linq Where,c#,linq,c#-4.0,linq-to-objects,C#,Linq,C# 4.0,Linq To Objects,基本要素: IDictionary扩展IEnumerable 使用LINQ时,编译器将查询语法转换为可枚举.Where方法的调用 当遍历此方法返回的IEnumerable时,谓词将对集合的每个项求值 根据结果生成相应的项目 这样的请求: var l_res = from n in List where n.key == 1 select n; 将遍历列表中的每个项目 如果List实现了IDictionary,并且where子句位于用作字典中键的属性上,我如何利用该键来避免遍历每个记录并执行查找

基本要素:

IDictionary
扩展
IEnumerable

使用LINQ时,编译器将查询语法转换为
可枚举.Where
方法的调用

当遍历此方法返回的
IEnumerable
时,谓词将对集合的每个项求值

根据结果生成相应的项目

这样的请求:

var l_res = from n in List where n.key == 1 select n;
将遍历
列表中的每个项目

如果
List
实现了
IDictionary
,并且
where
子句位于用作字典中键的属性上,我如何利用该键来避免遍历每个记录并执行查找

我已经知道我可以测试
IEnumerable
是否也是一个
IDictionary
实现,并选择使用哪一个是最好的请求:

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 ;
}
if(列表是IDictionary)
{
var l_res=((索引)列表)[1];
}
其他的
{
var l_res=列表中的n,其中n.key==1选择n;
}
但我想知道我是否遗漏了LINQ中存在的处理像这样的键控集合的东西


注意:LINQ-to0SQL提供程序使用
IQueryable
和表达式树来实现相同的功能,但我的问题是关于LINQ到对象。

不,您没有遗漏任何内容。唯一有知识的键控集合是,即使如此,它也没有做任何特殊的事情,它只是归结为一个事实,
Lookup
实现了
IEnumerable
;实际上,您正在迭代实现

这就是说,LINQ没有任何关于接口的特殊知识,除了;恰好扩展了
IEnumerable
,这就是为什么您可以首先对它执行操作的原因

但是,对于具有特定查找机制的任何类型,都需要嗅探该类型(通常在LINQ中完成),然后在可能的情况下调用特定于类型的操作。如果类型嗅探失败,您可以求助于使用
IEnumerable
的实现


正如您在这里所做的。

您可以在字典上实现一个自定义的
,其中
分析传入的表达式,如果它看起来像一个键控访问,请使用特殊的字典功能

在我看来,这只是一个理论上的选择。不应该这样做。相反,应该调整过滤机制,以便以正确的方式使用字典


还要注意的是,一旦您将不透明的
Func
传递给其他一些代码,这另一段代码就无法查看您传入的代理的内部。它无法注意到存在键控访问。这就是为什么linqto对象不能做到这一点。

您不使用
var l_res=((IDictionary)list)[1]的原因是什么?这真的是您的应用程序的性能问题还是您在进行微优化?嗯,没有任何理由。我正在通过.Net微框架编写OData提供程序。并希望避免使用IQueryable导致表达式树的巨大复杂性。然后我想确保在继续之前不会错过任何东西。。。
var l_res = from n in List where n.key == 1 select n;
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 ;
}