He venido a usar LINQ en mi programación diaria. De hecho, rara vez, si alguna vez, uso un ciclo explícito. Sin embargo, descubrí que ya no uso la sintaxis de SQL. Solo uso las funciones de extensión. Entonces, en lugar de decir:
from x in y select datatransform where filter
Yo suelo:
x.Where(c => filter).Select(c => datatransform)
¿Qué estilo de LINQ prefiere y con qué otros miembros de su equipo se sienten cómodos?
c#
coding-style
linq
Irlanda
fuente
fuente
Respuestas:
Me parece lamentable que la postura de Microsoft según la documentación de MSDN sea que la sintaxis de consulta es preferible, porque nunca la uso, pero uso la sintaxis del método LINQ todo el tiempo. Me encanta poder hacer consultas de una sola línea al contenido de mi corazón. Comparar:
A:
Más rápido, menos líneas, y para mis ojos se ve más limpio. La sintaxis de consulta tampoco admite todos los operadores estándar de LINQ. Una consulta de ejemplo que hice hace poco se parecía a esto:
Que yo sepa, para replicar esta consulta utilizando la sintaxis de consulta (en la medida de lo posible) se vería así:
No me parece más legible, y de todos modos necesitarías saber cómo usar la sintaxis del método. Personalmente, estoy realmente enamorado del estilo declarativo que LINQ hace posible y lo uso en cualquier situación en la que sea posible, tal vez a veces en mi detrimento. Caso en cuestión, con la sintaxis del método puedo hacer algo como esto:
Me imagino que el código anterior sería difícil de entender para alguien que entra en el proyecto sin una buena documentación, y si no tienen una sólida formación en LINQ, es posible que no lo entiendan de todos modos. Aún así, la sintaxis del método expone una capacidad bastante poderosa para proyectar rápidamente (en términos de líneas de código) una consulta para obtener información agregada sobre múltiples colecciones que de otro modo requerirían una gran cantidad de bucles foreach tediosos. En un caso como este, la sintaxis del método es ultra compacta para lo que obtienes de ella. Intentar hacer esto con la sintaxis de consulta puede volverse difícil de manejar bastante rápido.
fuente
La sintaxis funcional me parece más agradable a la vista. La única excepción es si necesito unir más de dos conjuntos. The Join () se vuelve loco muy rápido.
fuente
¿Es demasiado tarde para agregar otra respuesta?
He escrito un montón de código LINQ-to-objects y afirmo que, al menos en ese dominio, es bueno comprender ambas sintaxis para usar el código que sea más simple, que no siempre es sintaxis de puntos.
Por supuesto, hay momentos en que la sintaxis de puntos ES el camino a seguir; otros han proporcionado varios de estos casos; sin embargo, creo que las comprensiones se han modificado brevemente, dado un mal golpe, por así decirlo. Así que proporcionaré una muestra donde creo que las comprensiones son útiles.
Aquí hay una solución para un rompecabezas de sustitución de dígitos: (solución escrita usando LINQPad, pero puede ser independiente en una aplicación de consola)
... que produce:
No está mal, la lógica fluye linealmente y podemos ver que surge una única solución correcta. Este rompecabezas es bastante fácil de resolver a mano: razonando que 3>>
N
0 yO
> 4 * N implica 8> =O
> = 4. Eso significa que hay un máximo de 10 casos para probar a mano (2 paraN
-por- 5 paraO
) Me he desviado lo suficiente: este rompecabezas se ofrece con fines ilustrativos de LINQ.Transformaciones del compilador
El compilador hace mucho para traducir esto en sintaxis de puntos equivalente. Además de las segundas
from
cláusulasSelectMany
habituales y posteriores que se convierten en llamadas , tenemoslet
cláusulas que se convierten enSelect
llamadas con proyecciones, las cuales usan identificadores transparentes . Como estoy a punto de mostrar, tener que nombrar estos identificadores en la sintaxis de puntos elimina la legibilidad de ese enfoque.Tengo un truco para exponer lo que hace el compilador al traducir este código a la sintaxis de puntos. Si descomenta las dos líneas comentadas arriba y lo ejecuta nuevamente, obtendrá el siguiente resultado:
Colocando a cada operador LINQ en una nueva línea, traduciendo los identificadores "indescriptibles" a los que podemos "hablar", cambiando los tipos anónimos a su forma familiar y cambiando la
AndAlso
jerga del árbol de expresiones para&&
exponer las transformaciones que hace el compilador para llegar a un equivalente en sintaxis de puntos:Lo que si ejecuta puede verificar que salga nuevamente:
... pero ¿escribirías código como este?
Apuesto a que la respuesta es NONBHN (¡No solo no, sino que no!), Porque es demasiado complejo. Claro que puede encontrar algunos nombres de identificadores más significativos que "temp0" .. "temp3", pero el punto es que no agregan nada al código, no hacen que el código funcione mejor, no lo hacen haga que el código se lea mejor, solo lo desagradable, y si lo hiciera a mano, sin duda lo estropearía una o tres veces antes de hacerlo bien. Además, jugar "el juego de los nombres" es lo suficientemente difícil como para identificar identificadores significativos, por lo que agradezco el descanso del juego de nombres que el compilador me proporciona en la comprensión de consultas.
Es posible que esta muestra de rompecabezas no sea lo suficientemente real como para que la tome en serio; sin embargo, existen otros escenarios donde brillan las comprensiones de consultas:
Join
yGroupJoin
: el alcance de las variables de rango en lasjoin
cláusulas de comprensión de consultas convierten los errores que de otro modo podrían compilarse en sintaxis de puntos en errores de tiempo de compilación en la sintaxis de comprensión.from
cláusulas,join
yjoin..into
cláusulas ylet
cláusulas.Sé de más de un taller de ingeniería en mi ciudad natal que ha prohibido la sintaxis de comprensión. Creo que es una pena, ya que la sintaxis de comprensión no es más que una herramienta y una herramienta útil. Creo que es muy parecido a decir: "Hay cosas que puedes hacer con un destornillador que no puedes hacer con un cincel. Debido a que puedes usar un destornillador como cincel, los cinceles están prohibidos en adelante por decreto del rey".
fuente
Mi consejo es usar la sintaxis de comprensión de consultas cuando toda la expresión se puede hacer en la sintaxis de comprensión. Es decir, preferiría:
a
Pero preferiría
a
Ojalá hubiéramos creado una sintaxis que hiciera más agradable mezclar los dos. Algo como:
Pero lamentablemente no lo hicimos.
Pero básicamente, es una cuestión de preferencia. Haz el que te parezca mejor a ti y a tus compañeros de trabajo.
fuente
var londonCustomers = from c in ...; int count = londonCustomers.Count();
SQL-like es una buena manera de comenzar. Pero como es limitado (solo es compatible con las construcciones que admite su lenguaje actual), eventualmente los desarrolladores van al estilo de métodos de extensión.
Me gustaría señalar que hay algunos casos que pueden implementarse fácilmente con un estilo similar a SQL.
También puede combinar ambas formas en una consulta.
fuente
Tiendo a usar la sintaxis sin consulta a menos que necesite definir una variable a mitad de camino aunque la consulta como
pero escribo la sintaxis sin consulta como
fuente
Siempre uso las funciones de extensión debido a los pedidos. Tome su ejemplo simple, en el SQL, escribió select primero, aunque en realidad, donde se ejecutó primero. Cuando escribes usando los métodos de extensión, me siento mucho más en control. Recibo Intellisense sobre lo que se ofrece, escribo las cosas en el orden en que suceden.
fuente
También me gusta la función de extensión.
Tal vez porque es menos un salto de sintaxis en mi mente.
También se siente más legible a la vista, especialmente si está utilizando marcos de terceros que tienen api linq.
fuente
Aquí está la heurística que sigo:
Creo que las lambdas con combinaciones se ven desordenadas y son difíciles de leer.
fuente