我理解为什么IQueryable
和IEnumerable exist
,但我不清楚IQueryable
从IEnumerable
获得的好处。
我遇到的一个缺点:
任何创建自己的IEnumerable
扩展程序的人都可能会轻易将无辜的IQueryable
查询转换为效率低下的IEnumerable
调用。例如,使用MoreLinq:
Users.DistinctBy(u => u.Address).Where(u => u.Age >= 18)
(这将使用IEnumerable.Where
而不是IQueryable.Where
,除非我错过了IQueryable
以上的实施方式)
IQueryable
的工作方式,内部Expression
被链接语句改变,似乎与链接函数通常需要工作的方式完全不同。
我怀疑这个接口继承有一些强大的优势,我可能没有充分利用它。与IQueryable
实施IEnumerable
相比,有什么好处,例如,有一个执行查询的显式转换?
答案 0 :(得分:3)
(我做认为从IQueryable
继承IEnumerable
是愚蠢的)...但是!
它只是起作用
这是.NET中的leitmotif集合。如果要在Contains
集合上执行List<>
(执行O(n)操作),则没有安全网。如果您多次重新执行相同的查询,则没有安全网,因为您不知道IQueryable
和IEnumerable
之间的差异(请注意,即使IEnumerable
也没有&#39} ; t保证结果的缓存:-))。
由于这种继承,接受IEnumerable
/ IEnumerable<T>
的所有方法都接受IQueryable
/ IQueryable<T>
/ IOrderedQueryable<T>
它只是起作用
熟悉Variant数据类型的VB程序员团队...... .NET程序员团队会对慢查询感到满意: - )
与往常一样,这里有优雅的空间,并且有足够的空间进行草率编程。任何人都有空间: - )
我要补充一点,您提供的示例来自外部库,其说明为LINQ to Objects is missing a few desirable features.
(并注意DistinctBy
可以&#34;模拟&#34; GroupBy
+ Select(First())
,因此可以构建IQueryable兼容的)。所以你使用像螺丝一样的锤子,你抱怨它不是正确的仪器: - )
Microsoft提供的不会生成集合的扩展方法通常为IQueryable
- 安全(Expression
与Func
除外)
出于好奇,MSDN的正式理由是:
IQueryable接口继承IEnumerable接口,因此如果它表示查询,则可以枚举该查询的结果。枚举导致与IQueryable对象关联的表达式树被执行。
该接口继承IEnumerable&lt; T&gt;接口,以便如果它表示查询,则可以枚举该查询的结果。枚举强制与IQueryable&lt; T&gt;相关联的表达式树。要执行的对象。当调用Execute&lt; TResult&gt;(Expression)方法时,将执行不返回可枚举结果的查询。
可悲的是(至少对我来说),这不是一个足够好的理由,因为他们可以拥有
AsEnumerable()
以明确的方式完成工作或
IQueryable
中加入GetEnumerator()
(和相关的)接口,因为foreach
使用鸭子打字,它会很高兴。例如:
public interface IMyEnumerabe<T>
{
IEnumerator<T> GetEnumerator();
}
IMyEnumerabe<int> myenumerable = null;
foreach (int el in myenumerable)
{
// Compiles (and in this cases crashes with a NullReferenceException :-) )
}