J'en suis venu à utiliser beaucoup LINQ dans ma programmation quotidienne. En fait, j'utilise rarement, voire jamais, une boucle explicite. J'ai cependant constaté que je n'utilise plus la syntaxe SQL. J'utilise juste les fonctions d'extension. Alors plutôt dire:
from x in y select datatransform where filter
J'utilise:
x.Where(c => filter).Select(c => datatransform)
Quel style de LINQ préférez-vous et avec quoi les autres membres de votre équipe sont-ils à l'aise?
c#
coding-style
linq
Erin
la source
la source
Réponses:
Je trouve regrettable que la position de Microsoft selon la documentation MSDN soit que la syntaxe de requête soit préférable, car je ne l'utilise jamais, mais j'utilise tout le temps la syntaxe de la méthode LINQ. J'adore pouvoir lancer des requêtes à une ligne au contenu de mon cœur. Comparer:
À:
Plus rapide, moins de lignes et à mes yeux semble plus propre. La syntaxe de requête ne prend pas non plus en charge tous les opérateurs LINQ standard. Un exemple de requête que j'ai récemment faite ressemblait à ceci:
À ma connaissance, pour reproduire cette requête en utilisant la syntaxe de requête (dans la mesure du possible), cela ressemblerait à ceci:
Cela ne me semble pas plus lisible et vous devez de toute façon savoir utiliser la syntaxe des méthodes. Personnellement, je suis vraiment amoureux du style déclaratif que LINQ rend possible et je l'utilise dans toutes les situations où cela est possible - peut-être parfois à mon détriment. Par exemple, avec la syntaxe de la méthode, je peux faire quelque chose comme ceci:
J'imagine que le code ci-dessus serait difficile à comprendre pour quelqu'un entrant dans le projet sans une bonne documentation, et s'il n'a pas une solide expérience en LINQ, il pourrait ne pas le comprendre de toute façon. Pourtant, la syntaxe de la méthode expose certaines capacités assez puissantes pour projeter rapidement (en termes de lignes de code) une requête pour obtenir des informations agrégées sur plusieurs collections qui autrement prendraient beaucoup de temps pour chaque boucle fastidieuse. Dans un cas comme celui-ci, la syntaxe de la méthode est ultra compacte pour ce que vous en retirez. Essayer de le faire avec la syntaxe de la requête peut devenir difficile à gérer assez rapidement.
la source
Je trouve la syntaxe fonctionnelle plus agréable à l'œil. La seule exception est si je dois rejoindre plus de deux ensembles. Le Join () devient fou très rapidement.
la source
Est-il trop tard pour ajouter une autre réponse?
J'ai écrit une tonne de code LINQ-to-objects et je soutiens qu'au moins dans ce domaine, il est bon de comprendre les deux syntaxes afin d'utiliser ce qui rend le code plus simple - ce qui n'est pas toujours la syntaxe à points.
Bien sûr, il y a des moments où la syntaxe à points EST la voie à suivre - d'autres ont fourni plusieurs de ces cas; cependant, je pense que les compréhensions ont été brièvement modifiées - étant donné un mauvais rap, si vous voulez. Je vais donc fournir un exemple où je pense que les compréhensions sont utiles.
Voici une solution à un casse-tête de substitution de chiffres: (solution écrite à l'aide de LINQPad, mais peut être autonome dans une application console)
... qui produit:
Pas trop mal, la logique s'écoule linéairement et nous pouvons voir qu'elle propose une seule solution correcte. Ce casse-tête est assez facile à résoudre à la main: raisonner que 3>>
N
0 etO
> 4 * N implique 8> =O
> = 4. Cela signifie qu'il y a un maximum de 10 cas à tester à la main (2 pourN
-par- 5 pourO
). J'ai assez erré - ce puzzle est proposé à des fins d'illustration LINQ.Transformations du compilateur
Le compilateur fait beaucoup pour traduire cela en syntaxe point équivalente. Outre la seconde
from
clauseSelectMany
habituelle et les clauses suivantes qui sont transformées en appels, nous avons deslet
clauses qui deviennent desSelect
appels avec des projections, qui utilisent tous deux des identificateurs transparents . Comme je vais le montrer, le fait de devoir nommer ces identificateurs dans la syntaxe à points enlève à la lisibilité de cette approche.J'ai une astuce pour exposer ce que le compilateur fait en traduisant ce code en syntaxe à points. Si vous décommentez les deux lignes commentées ci-dessus et l'exécutez à nouveau, vous obtiendrez la sortie suivante:
Mettre chaque opérateur LINQ sur une nouvelle ligne, traduire les identificateurs "indescriptibles" en ceux que nous pouvons "parler", changer les types anonymes en leur forme familière et changer le
AndAlso
jargon de l'arborescence d'expressions pour&&
exposer les transformations que fait le compilateur pour arriver à un équivalent en syntaxe à points:Si vous exécutez, vous pouvez vérifier qu'il renvoie à nouveau:
... mais écririez-vous jamais du code comme celui-ci?
Je parierais que la réponse est NONBHN (non seulement non, mais enfer non!) - parce que c'est tout simplement trop complexe. Bien sûr, vous pouvez trouver des noms d'identificateurs plus significatifs que "temp0" .. "temp3", mais le fait est qu'ils n'ajoutent rien au code - ils n'améliorent pas le code, ils ne le font pas mieux rendre le code plus lisible, ils ne font que vider le code, et si vous le faisiez à la main, vous le gâcheriez sans doute une ou trois fois avant de le faire correctement. De plus, jouer au "jeu de noms" est assez difficile pour des identifiants significatifs, donc je me réjouis de la rupture avec le jeu de noms que le compilateur me fournit dans les compréhensions de requêtes.
Cet exemple de puzzle peut ne pas être assez réel pour que vous le preniez au sérieux; cependant, d'autres scénarios existent où les compréhensions de requête brillent:
Join
etGroupJoin
: l'étendue des variables de plage dans lesjoin
clauses de compréhension des requêtes transforme les erreurs qui pourraient autrement se compiler en syntaxe à points en erreurs au moment de la compilation dans la syntaxe de compréhension.from
clauses,join
&join..into
clauses etlet
clauses.Je connais plus d'un atelier d'ingénierie dans ma ville natale qui a interdit la syntaxe de compréhension. Je pense que c'est dommage car la syntaxe de compréhension n'est qu'un outil et un outil utile à cela. Je pense que c'est un peu comme dire: "Il y a des choses que vous pouvez faire avec un tournevis que vous ne pouvez pas faire avec un burin. Parce que vous pouvez utiliser un tournevis comme burin, les burins sont désormais interdits par décret du roi."
la source
Mon conseil est d'utiliser la syntaxe de compréhension des requêtes lorsque l'expression entière peut être effectuée dans la syntaxe de compréhension. Autrement dit, je préférerais:
à
Mais je préfère
à
Je souhaite que nous ayons trouvé une syntaxe qui a rendu plus agréable de mélanger les deux. Quelque chose comme:
Mais malheureusement, nous ne l'avons pas fait.
Mais en gros, c'est une question de préférence. Faites celui qui vous convient le mieux ainsi qu'à vos collègues.
la source
var londonCustomers = from c in ...; int count = londonCustomers.Count();
Le SQL-like est une bonne façon de commencer. Mais comme il est limité (il ne prend en charge que les constructions prises en charge par votre langage actuel), les développeurs finissent par adopter le style des méthodes d'extension.
Je voudrais noter qu'il existe certains cas qui peuvent être facilement mis en œuvre par un style similaire à SQL.
Vous pouvez également combiner les deux façons dans une même requête.
la source
J'ai tendance à utiliser la syntaxe sans requête, sauf si je dois définir une variable à mi-chemin si la requête comme
mais j'écris la syntaxe non-requête comme
la source
J'utilise toujours les fonctions d'extension à cause de la commande. Prenez votre exemple simple - dans le SQL, vous avez écrit select first - même si en fait, le où a été exécuté en premier. Lorsque vous écrivez en utilisant les méthodes d'extension, je me sens beaucoup plus en contrôle. Je reçois Intellisense sur ce qui est proposé, j'écris les choses dans l'ordre où elles se produisent.
la source
J'aime aussi la fonction d'extension.
Peut-être parce que c'est moins un saut de syntaxe dans mon esprit.
Cela semble plus lisible à l'œil aussi, surtout si vous utilisez des frameworks tiers qui ont linq api.
la source
Voici l'heuristique que je suis:
Je pense que les lambdas avec jointures semblent désordonnés et difficiles à lire.
la source