C# 芬德尔Vs何处
我有一个C# 芬德尔Vs何处,c#,.net,linq,list,ienumerable,C#,.net,Linq,List,Ienumerable,我有一个IEnumerable,我想基于LINQ谓词进行过滤。我试着像往常一样在IEnumerable上使用Where,但这次我偶然发现了一些有趣的东西。使用谓词调用IEnumerable上的Where时,我得到一个空列表作为返回。我知道它必须生成一个包含两项的列表。如果我用相同的谓词使用FindAll,那么它将生成正确的结果 谁能向我解释一下,为什么会这样?我一直认为Where是FindAll的一种惰性版本,它还返回IEnumerable,而不是列表。肯定还有比这更重要的事?(我做了一些研究,
IEnumerable
,我想基于LINQ谓词进行过滤。我试着像往常一样在IEnumerable
上使用Where
,但这次我偶然发现了一些有趣的东西。使用谓词调用IEnumerable
上的Where时,我得到一个空列表作为返回。我知道它必须生成一个包含两项的列表。如果我用相同的谓词使用FindAll
,那么它将生成正确的结果
谁能向我解释一下,为什么会这样?我一直认为Where
是FindAll
的一种惰性版本,它还返回IEnumerable
,而不是列表。肯定还有比这更重要的事?(我做了一些研究,但没有结果。)
代码:
IEnumerable views=currentProject.views.Where(
v=>v.Entries.Any(e=>e.Type==InputType.IMAGE | e.Type==InputType.VIDEO));
IEnumerable views=currentProject.views.FindAll(
v=>v.Entries.Any(e=>e.Type==InputType.IMAGE | e.Type==InputType.VIDEO));
您可以在此处找到答案:。基本上,如果在“Where”上调用.ToList(),它们将是相同的
您可以找到有关延迟执行和立即执行之间差异的更多信息:我的最佳猜测是,在调用Where(创建枚举数)和代码中实际使用结果的位置(例如,从ToList调用该枚举数的MoveNext和(get_)Current)之间发生了一些事情). 是的,这里是findall的懒惰版本。FindAll()是列表类型的函数,它不是像Where那样的LINQ扩展方法。List上的FindAll方法,它是一个实例方法,返回具有相同元素类型的新列表。FindAll只能用于列表实例,而LINQ扩展方法可用于实现IEnumerable的任何类型
主要的区别(除了它们的实现方式:IEnumerable和List)在于Where实现了延迟执行,而Where在您需要它之前实际上不会执行查找(例如在foreach循环中使用它)。FindAll是一种立即执行方法
我将引用一个称为表达式树的数据结构来理解延迟执行,您只需要理解表达式树是一个类似于列表或队列的数据结构。它保存的LINQ to SQL查询不是查询结果,而是查询本身的实际元素
要理解在哪里工作,我们需要了解如果我们编写代码
var query = from customer in db.Customers
where customer.City == "Paris"
select customer;
查询不在此处执行,而在foreach循环中执行
要理解列表,FindAll
返回一个列表
,而其中
返回一个IEnumerable
。但是其中
使用了延迟执行,所以只有当你具体化它时才能得到它,例如使用ToList
。你为什么不把它作为一个答案呢?:)比这里唯一的答案更好的解释,它发布的时间比你的评论晚。尽管你的评论回答了问题,但已经发布了答案,我知道:)我知道你所说的可能只是对两者之间差异的简单解释,但我明白你的意思。谢谢这里的问题是,在IEnumerable上使用Where()时,我没有调用.ToList(),因此检查它时会显示一个空列表。
var query = from customer in db.Customers
where customer.City == "Paris"
select customer;