这两个linq表达式在功能上是等价的吗?

时间:2010-11-23 21:35:39

标签: c# linq

之间是否有任何功能差异:

if (photos.Any(it => it.Archived))

if (photos.Where(it => it.Archived).Any())

如果是这样,是否有更令人信服的理由使用其中一个?

3 个答案:

答案 0 :(得分:8)

从功能上讲,他们做同样的事情。性能取决于特定的提供程序,但是例如在LINQ to SQL中,两种形式都生成完全相同的SQL:

SELECT 
    (CASE 
        WHEN EXISTS(
            SELECT NULL AS [EMPTY]
            FROM [dbo].[photos] AS [t0]
            WHERE [t0].[Archived] = 1
            ) THEN 1
        ELSE 0
     END) AS [value]

如果我必须选择一个,我会使用第一个选项,因为它对我来说似乎更加清晰。

答案 1 :(得分:2)

不,这些方法的当前.NET Framework实现没有区别实际差异。由于延迟执行,两者都会枚举photos,直到找到匹配,然后停止。 (假设这是Linq到对象 - 其他提供者可能表现不同)。

如果你想挑剔,那么实施方面的差异很小。 (您可以在框架源中查找):

Any只是使用foreach迭代集合,而Where返回WhereArrayIteratorWhereListIteratorWhereEnumerableIterator,具体取决于收集的类型你传入了。我没有深入研究过这个问题,但我想这样做是为了在使用数组或列表的情况下允许链式扩展方法进行优化。

换句话说,Any包含简单的foreachWhere执行此操作:

    if (source is TSource[]) return new WhereArrayIterator<TSource>((TSource[])source, predicate); 
    if (source is List<TSource>) return new WhereListIterator<TSource>((List<TSource>)source, predicate);
    return new WhereEnumerableIterator<TSource>(source, predicate);

答案 2 :(得分:2)

作为表达式,它们产生相同的结果。但是,产生这种结果的机制略有不同。请注意,它们都会从原始序列中浏览相同数量的项目。

我总是使用前者,因为它更短,并且在第二次选择它时不会失去清晰度,可读性和可维护性。