Mic*_*ker 4 c# linq ienumerable iqueryable
我明白为什么IQueryable和IEnumerable exist,但我不清楚从IQueryable中获得什么好处IEnumerable。
我遇到的缺点之一:
任何创建自己的IEnumerable扩展方法的人都可能很容易意外地将看似无辜的IQueryable查询转换为低效的IEnumerable调用。例如,使用 MoreLinq:
Users.DistinctBy(u => u.Address).Where(u => u.Age >= 18)
Run Code Online (Sandbox Code Playgroud)(这将使用IEnumerable.Where而不是IQueryable.Where除非我错过了IQueryable上述的实现)
其工作方式(通过链式语句更改的IQueryable内部)似乎与链式函数通常预期的工作方式截然不同。Expression
我怀疑这个接口继承有一些强大的优点,但我可能没有充分利用这些优点。与执行查询的显式转换相比,IQueryable实现有什么好处?IEnumerable
(我确实IQueryable认为继承自是愚蠢的IEnumerable)...但是!
它就是有效的
这是.NET 中集合的主题。Contains如果您想对集合执行操作List<>(执行 O(n) 操作),则没有安全网。如果您多次重新执行相同的查询,则没有安全网,因为您不知道IQueryable和之间的区别IEnumerable(并且请注意,即使IEnumerable不能保证结果的缓存:-))。
由于这种继承,所有接受IEnumerable/的方法都IEnumerable<T>接受IQueryable//IQueryable<T>IOrderedQueryable<T>
它就是有效的
大量的 VB 程序员对 Variant 数据类型感到满意...大量的 .NET 程序员会对缓慢的查询感到满意:-)
一如既往,有卓越的空间,也有草率编程的空间。任何人都有空间:-)
我要补充一点,您给出的示例来自外部库,并带有说明LINQ to Objects is missing a few desirable features.
(请注意,DistinctBy可以使用GroupBy+ “模拟” Select(First()),因此可以将其构建为与 IQueryable 兼容)。所以你像使用螺丝一样使用锤子,并且抱怨这不是正确的工具:-)
Microsoft 提供的不生成集合的扩展方法通常是IQueryable安全的(除了Expressionvs Func)
出于好奇,MSDN官方给出的理由是:
IQueryable 接口继承了 IEnumerable 接口,因此如果它表示一个查询,则可以枚举该查询的结果。枚举会导致执行与 IQueryable 对象关联的表达式树。
该接口继承了 IEnumerable<T> 接口,因此如果它表示一个查询,则可以枚举该查询的结果。枚举强制执行与 IQueryable<T> 对象关联的表达式树。调用 Execute<TResult>(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 :-) )
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
871 次 |
| 最近记录: |