2011-10-04 20 views
9

Si tengo una lista de mensajes en una arquitectura de publicación/suscripción, supongo que es razonable usar IEnumerable.Where en una lista subyacente para recuperar mensajes particulares y confiar en el orden de los mensajes?¿El método de extensión LINQ está garantizado para conservar el orden?

+0

Tenga en cuenta que en realidad no existe ningún método como 'IEnumerable.Where'. Hay un método de extensión 'Enumerable.Where' que acepta un' IEnumerable '. ¡Pero es muy posible que una consulta LINQ determinada use algo diferente para un tipo enumerable dado! Y puede implementarse de una manera que preserve la orden o no la preserve. –

+0

Sé que no es un miembro sino un método de extensión. Simplemente fue más fácil escribir y supongo que todo el mundo sabe sobre los métodos de extensión linq. – LinusK

+0

Solo recuerde que un tipo enumerable determinado podría definir su propio método 'Where()', que podría usarse en lugar de 'Enumerable.Where()', según el tipo de la referencia que está enumerando. –

Respuesta

20

El método de extensión Enumerable.Where lo hará, pero el método de extensión Queryable.Where no lo hará.

Enumerable.Where tiene que conservar el orden, ya que transmite los resultados y no hay caché (y no hay lógica en los resultados de almacenamiento en caché).

Queryable.Where, por otro lado, traduce la consulta dada a algo que el origen de datos subyacente entenderá y no hay ninguna garantía sobre el orden que nunca. Este efecto se puede observar fácilmente cuando se trabaja con bases de datos relacionales. La adición de una cláusula where puede permitir que la base de datos elija otro índice, lo que puede cambiar el orden de los resultados.

+0

De hecho, está documentado que LINQ to Entities * no * conserva el orden después de un '.Where()' –

+4

Si bien es cierto que 'Enumerable.Where' actualmente conserva el orden, no veo nada en la documentación de la interfaz que garantice . Y, por supuesto, todas las apuestas están apagadas si estás usando 'ParallelEnumerable'. –

+1

@Jim: acepto que la documentación de 'Enumerable.Where' no indica que se mantendrá el orden, pero creo que es seguro asumir que siempre conservará el orden, porque aún sería un cambio de comportamiento bastante grande que una gran cantidad de los desarrolladores dependen de. – Steven

7

Para Linq to Objects/IEnumerable esto es cierto - se mantendrá el orden - para los proveedores de IQueryable depende del proveedor, muchos proveedores no mantienen el orden.

Parece que este hecho (mantener el orden) no está documentado en MSDN, por lo que lo consideraría un detalle de implementación que, aunque poco probable, podría cambiar en el futuro.

+0

¿Está documentada la interfaz para 'IEnumerable' para conservar el orden? ¿O simplemente "sabemos" que lo hará? –

+0

@Jim, 'IEnumerable' no tiene' Where' en absoluto. Es un método de extensión y un patrón de consulta, pero no es miembro de la interfaz. –

+0

@CraigStuntz: Bien. 'Enumerable.Where', entonces. No veo la documentación que dice que preservará el orden. –

Cuestiones relacionadas