Saltar al contenido

Racionalizando el código LINQ con Let

Dejemos que las declaraciones puedan funcionar como miniaturas donde las declaraciones. Considere esta lista de animales:

1234567var animals =newList<Animal..; {nuevoAnimal{Nombre ="Ballena", Clase ="Mamífero", Ubicación ="Océano"},nuevoAnimal{Nombre ="Oso", Clase ="Mamífero", Ubicación ="Bosque"},nuevoAnimal{Nombre ="Halcón", Clase ="Pájaro", Ubicación ="Bosque"},nuevoAnimal{Nombre ="Atún", Clase ="Pez", Ubicación ="Océano"}};

csharp

Racionalizando el código LINQ con Let
Racionalizando el código LINQ con Let

Digamos que queremos devolver una lista de animales que:

  1. No dan miedo
  2. Es uno de nuestros animales favoritos de la lista
  3. Vive en el bosque

La siguiente consulta devolverá esos resultados:

12345de un en animalesdonde!(newList<string;{"Oso", "Tiburón"}.Contiene(a.Nombre))&&newList<string;{"Halcón", "Tiburón"}.Contiene(a.Nombre)&& a.Ubicación =="Bosque "select a;

csharp

Esto es un poco confuso porque el significado de las dos listas, la del oso y el tiburón y la del halcón y el tiburón, arriba es ambiguo. El promotor puede haber sabido cuál era su favorito y cuáles daban miedo (y cuál era la relación entre esas dos listas) en el momento en que lo escribió pero, mirándolo una semana después, es difícil saberlo.

Poniendo en claro, la pregunta anterior dice:

Dame los animales de la lista de animales de tal manera que esta lista: «Oso», «Tiburón» no contiene el nombre, y esta lista: «Halcón», «Tiburón» contiene el nombre, y la ubicación es «Bosque».

No hay ninguna duplicación aquí para que la declaración let se resuelva, pero podemos hacer todo mucho más claro al usarla:

12345678var results =from a in animalslet favoriteAnimals =newList<string Contiene(a.Nombre)let isScary = asustadizoAnimales.Contiene(a.Nombre)let livesInTheWoods = a.Ubicación =="Bosque "where(!isScary && isFavorite && livesInTheWoods)select a;

csharp

Aquí, definimos nuestras listas, los Animales favoritos y los Animales temibles, en línea en la consulta. Luego creamos dos variables booleanas que reflejan si el nombre de un animal dado está en esa lista. Luego añadimos una variable livesInTheWoods que comprueba la Ubicación y concatenamos estos tres elementos juntos en la cláusula where.

El resultado de ambas consultas es Halcón – mi único animal favorito del que no tengo miedo y que vive en el bosque. Ambas preguntas son totalmente correctas, pero la segunda refleja el significado de los conjuntos mucho más claramente. Si, más tarde, decido que ya no tengo miedo a los tiburones, está perfectamente claro que debo eliminar ese elemento de la lista de animales temibles. Compara eso con la consulta anterior:

12345de un en animalesdonde!(newList<string;{"Oso", "Tiburón"}.Contiene(a.Nombre))&&newList<string;{"Halcón", "Tiburón"}.Contiene(a.Nombre)&& a.Ubicación =="Bosque "select a;

csharp

Si ya no me asustan los tiburones, ¿de qué lista hay que quitar eso? ¿La primera o la segunda?

Es importante considerar que este enfoque dejó resultó en una consulta mucho más larga. Pero más corta no siempre es mejor y menos código no siempre es mejor que más. A veces vale la pena unas pocas líneas de código extra si el compromiso es un aumento significativo de la claridad.