2010-11-23 20 views
7

¿hay alguna diferencia funcional entre:son estas dos expresiones linq funcionalmente equivalentes?

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

y

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

si es así, ¿hay alguna razón más convincente para utilizar uno sobre el otro?

+0

Los resultados de esto deberían ser los mismos, pero como no estoy 100% seguro de si hay alguna diferencia en el rendimiento, lo dejaré ir y dejaré que alguien con una respuesta definitiva en este post lo publique. –

+0

En Visual Studio puede investigar el IL usted mismo. Por favor, un punto de interrupción en el funktion –

Respuesta

8

Funcionalmente que hacen lo mismo. El rendimiento depende del proveedor específico, pero por ejemplo en LINQ to SQL ambas formas producir exactamente el mismo 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] 

Si tengo que elegir uno que haría uso de la primera opción, ya que parece un poco más claro para yo.

+1

+1 para la sugerencia de que la implementación real depende del proveedor. –

+0

@Tim Jarvis: Gracias. Lo reformulé de solo una "sugerencia" para hacerlo un poco más explícito de que es específico del proveedor. –

2

No, no hay diferencia diferencia práctica para la implementación actual de .NET Framework de los métodos. Debido a la ejecución diferida, ambos enumerarán photos hasta que encuentre una coincidencia y luego se detendrá. (Siempre que esto sea Linq-to-objects, otros proveedores pueden comportarse de manera diferente).

Si desea obtener nit-picky, existen pequeñas diferencias de implementación. (Puede buscarlo en las fuentes de marco):

Any simplemente itera la colección usando foreach, donde como Where devuelve un WhereArrayIterator, WhereListIterator, o una WhereEnumerableIterator dependiendo de qué tipo de colección se pasa en I haven'. He investigado esto en profundidad, pero supongo que esto se hace para permitir que los métodos de extensión encadenados se optimicen en caso de que se use una matriz o una lista.

En otras palabras, ¿dónde Any contiene un simple foreach, Where hace esto:

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); 
+0

Pensé que cualquiera arrojó una ArgumentNullException si se le da un predicado nulo como sería el caso en la segunda versión, pero entonces no uso LINQ tanto. – stonemetal

+0

Ambos lanzamientos en nulo. – driis

+0

gracias por delinear las partes internas. – CedricB

2

Como expresión, producen el mismo resultado. Sin embargo, el mecanismo que produce este resultado es ligeramente diferente. Sin embargo, tenga en cuenta que ambos recorren la misma cantidad de elementos de la secuencia original.

Siempre usaré el primero ya que es más corto y no hay pérdida de claridad, legibilidad ni mantenimiento al elegirlo en el segundo.

Cuestiones relacionadas