Je suis en train de discuter avec un collègue sur Linq, je vais copier ici:
Co-travailleur: soyons honnêtes ici. La syntaxe Linq est nulle. C'est déroutant et non intuitif.
Moi: oh allez, plus déroutant que T-SQL?
Co-travailleur: euh, oui.
Moi: il a les mêmes parties de base, sélectionnez, où et à partir de
Co-travailleur: Linq, pour moi, est une bâtarde de relationnel + OO. Co-Worker: Ne vous méprenez pas, c'est incroyablement puissant, mais ils ont réutilisé le code SQL pour utiliser des collections d'objets identiques.
Je suis d'avis que l'utilisation de Linq + Lamda est très puissante (il est d'accord) et facilite également la lecture du code (il n'est pas d'accord sur ce point):
pickFiles = from f in pickFolder.GetFiles("*.txt")
where ValidAuditFileName.IsMatch(f.Name)
select f;
ou
var existing = from s in ActiveRecordLinq.AsQueryable<ScannedEntity>()
where s.FileName == f.FullName && s.DocumentType != "Unknown"
select s;
ou (code VB ici)
Dim notVerified = From image In images.AsParallel
Group Join verifyFile In verifyFolder.GetFiles("*.vfy").AsParallel.Where(
Function(v) v.Length > 0
).AsParallel
On image.Name.Replace(image.Extension, ".vfy") Equals verifyFile.Name
Into verifyList = Group
From verify In verifyList.DefaultIfEmpty
Where verify Is Nothing
Select verify
Pour moi, cela est clair et facile (au moins plus facile que les alternatives) à lire, quelles sont vos opinions à ce sujet?
la source
Réponses:
Je ne trouve plus le bon post, mais Eric Lippert (et peut-être plusieurs autres logiciels) a déjà exprimé son opinion sur le caractère déclaratif de Linq , qui, pour plusieurs classes de problèmes, est bien plus intuitif que la syntaxe impérative .
Linq vous permet d'écrire du code qui exprime l' intention , pas le mécanisme .
Vous me dites ce qui est le plus facile à lire. Cette:
Ou ca?
Ou même ça?
Le premier exemple est juste un tas de passe-partout inutiles pour obtenir les résultats les plus simples. Quiconque pense qu'il est plus lisible que les versions de Linq doit faire examiner sa tête. Non seulement cela, mais le premier gaspille de la mémoire. Vous ne pouvez même pas l'écrire en utilisant à
yield return
cause du tri.Votre collègue peut dire ce qu'il veut. Personnellement, je pense que Linq a considérablement amélioré la lisibilité de mon code.
Il n'y a rien de "relationnel" à propos de Linq non plus. Il peut avoir des similitudes superficielles avec SQL mais il ne tente en aucun cas de mettre en œuvre un calcul relationnel. C'est juste un tas d'extensions qui facilitent les requêtes et les séquences de projet. "Requête" ne signifie pas "relationnel", et plusieurs bases de données non relationnelles utilisent une syntaxe semblable à celle de SQL. Linq est purement orienté objet, il arrive juste de travailler avec des bases de données relationnelles à travers des frameworks tels que Linq to SQL en raison de l'arborescence des expressions voodoo et de la conception intelligente de l'équipe C #, rendant les fonctions anonymes convertibles implicitement en arborescences d'expression.
la source
Linq is purely object-oriented
+1 pour cela. C'est également la raison pour laquelle notre guide de style d'équipe impose l'utilisation de la syntaxe fluide par rapport à la syntaxe de requête. Je trouve que cela rend la nature OO du lien plus évidente pour quelqu'un habitué à objecter la notation dans les langages C-like.GetVipCustomers()
, ce qui, comme son nom l'indique, ne doit renvoyer qu'une collection de clients VIP, dans un ordre arbitraire. Dans les rares cas où l'ordre est important, tel que l'affichage à l'écran, laissez l'appelant trier la collection.Vous ne pouvez pas discuter avec cette critique. Pour votre collègue, ça craint . Nous n'avons pas réussi à concevoir une syntaxe qui, pour eux, était claire et intuitive. C'est notre échec et vous pouvez transmettre mes excuses à votre collègue. Je suis heureux de prendre des suggestions sur la façon de l'améliorer. qu'est-ce que votre collègue trouve spécifiquement déroutant ou peu intuitif?
Cependant, vous ne pouvez pas plaire à tout le monde. Mon opinion personnelle, et l'opinion de la plupart des personnes à qui j'ai parlé sur le sujet, est que la syntaxe de compréhension de requête est beaucoup plus claire que la syntaxe impérative équivalente. Il est clair que tout le monde n’est pas d’accord, mais heureusement, nous n’exigeons pas l’unanimité des millions de nos clients lorsque nous concevons le langage.
Au sujet de ce qui est "intuitif" cependant, je me souviens de l'histoire du linguiste anglais qui a étudié de nombreuses langues et qui a finalement conclu que l'anglais était la meilleure de toutes les langues, car en anglais, les mots viennent dans le même ordre pense les . Contrairement au français, où ils disent constamment des choses comme "le chien blanc mange la viande rouge". Comme il doit être difficile pour les Français de penser les mots dans le bon ordre et de les dire ensuite dans l’ ordre français ! Le français est tellement peu intuitif! C'est incroyable que les Français réussissent à le parler. Et allemand? où ils pensent "le chien mange de la viande" mais il faut ensuite dire "le chien que la viande mange"!?!
Souvent, ce qui est "intuitif" est simplement une question de familiarité. Il m'a fallu des mois de travail avec LINQ avant d'arrêter de commencer mes requêtes avec la clause "select". Maintenant, c'est une seconde nature et l'ordre SQL semble bizarre.
Ce que c'est! Les règles de portée sont toutes confondues dans SQL. Vous voudrez peut-être signaler à votre collègue que LINQ a été soigneusement conçu pour que (1) l'introduction des variables et des étendues se déroule de gauche à droite (*) et (2) l'ordre d'affichage de la requête sur la page. l'ordre dans lequel il est exécuté. C'est-à-dire quand vous dites
le c apparaît dans la portée à gauche et reste dans la droite. Et l'ordre dans lequel les choses se passent est: le premier "client" est évalué. Ensuite, le "où" est évalué pour filtrer la séquence. Ensuite, la séquence filtrée est projetée par le "select".
SQL n'a pas cette propriété. Si tu le dis
alors "Nom" est amené dans le champ d'application par quelque chose à sa droite, pas à sa gauche, et la requête est exécutée dans un ordre complètement foiré; la clause du milieu est évaluée en premier, puis la dernière, puis la première. Cela me semble fou et peu intuitif, ayant travaillé uniquement avec LINQ depuis si longtemps.
(*) Les règles de cadrage sont un peu bizarres dans LINQ avec des clauses de jointure. Mais à part cela, les scopes nichent bien.
la source
c.
l'EDI connaît déjà le type dec
et peut vous donner IntelliSense. Dans LINQ, vous dites "de c dans les clients où c." et boum, IntelliSense vous aide en listant les membres deCustomer
. En SQL, lorsque vous tapez "nom SELECT parmi les clients", vous ne pouvez obtenir aucune aide de l'EDI pour vous dire que "nom" est un bon choix, car vous avez déjà saisiname
auparavantcustomers
.Comme n'importe quoi d'autre dans le monde de la programmation, il faut s'habituer à la syntaxe, et ensuite, elle est (potentiellement) plus facile à lire.
Comme n'importe quoi d'autre dans le monde de la programmation, il existe un risque de code spaghetti ou d'autres abus.
Comme n'importe quoi d'autre dans le monde de la programmation, vous pouvez le faire de cette manière ou d'une autre manière.
Comme toute autre chose dans le monde de la programmation, votre kilométrage peut varier.
la source
J'ai vu un commentaire / une remarque où il est dit quelque chose - par rapport à LINQ / lambda - dans le sens de: "Écrivez un code lisible par les humains, plutôt que par votre ordinateur".
Je pense que cette déclaration a beaucoup de mérite, cependant, considérons le développeur (comme moi-même) qui a traversé toute la gamme des langages de développement depuis Assembly, en passant par la procédure, en passant par OO, en passant par la gestion, en exploitant des solutions parallèles de tâches à haut débit. .
Je suis fier de rendre mon code aussi lisible et réutilisable que possible et d'adopter de nombreux principes de modèle de conception GOF afin de fournir des systèmes et des services de qualité de la production dans un grand nombre de secteurs d'activité différents.
La première fois que j'ai rencontré l'expression lambda, j'ai pensé: "Qu'est-ce que c'est que ça!?!" C'était immédiatement contre-intuitif par rapport à ma syntaxe déclarative explicite bien connue (et donc confortable). Les plus jeunes <5 ans dans le boulot, cependant, ont tout gâché comme si c'était de la manne du paradis!
En effet, pendant des années, penser comme un ordinateur (au sens syntaxique) se traduit très facilement en syntaxe de codage direct (quelle que soit la langue). Lorsque vous avez cet état d'esprit informatique depuis environ 20 ans (30 ans et plus dans mon cas), vous devez comprendre que le choc syntaxique initial de l'expression lambda peut facilement se traduire par la peur et la méfiance.
Peut-être que le collègue du PO était issu d'un milieu similaire au mien (c.-à-d. Passé autour du bloc à quelques reprises) et que c'était contre-intuitif pour eux à cette époque? Ma question est: qu'avez-vous fait à ce sujet? Avez-vous essayé de rééduquer votre pair pour qu'il comprenne les avantages de la syntaxe en ligne, ou est-ce que vous le pilori / ostracisez-le pour ne pas "être avec le programme"? Les premiers auraient probablement vu votre collègue se rallier à votre pensée, les seconds leur auraient probablement fait se méfier encore plus de la syntaxe LINQ / lambda et exacerber ainsi l'opinion négative.
Pour moi, je devais rééduquer ma propre façon de penser (comme le dit Eric ci-dessus, ce n'est pas un changement de mental insignifiant, et je devais programmer à Miranda dans les années 80, alors j'ai eu mon lot d'expérience en programmation fonctionnelle). mais une fois que j’ai vécu cette douleur, les avantages étaient évidents, mais plus important encore, là où son utilisation était trop utilisée (c’est-à-dire pour l’utiliser), complexe et répétitive (compte tenu du principe DRY dans ce cas).
En tant que personne qui non seulement écrit encore beaucoup de code mais qui doit également réviser techniquement beaucoup de code, il était impératif que je comprenne ces principes afin de pouvoir examiner les éléments de manière impartiale et d'indiquer les endroits où l'utilisation d'une expression lambda peut être plus efficace / lisible, et aussi pour amener les développeurs à considérer la lisibilité d'expressions lambda en ligne très complexes (lorsqu'un appel de méthode rendrait, dans ces cas, le code plus lisible, maintenable et extensible).
Donc, quand quelqu'un dit qu'il "ne reçoit pas de lambda?" ou la syntaxe LINQ, plutôt que de les qualifier de luddites, essayez de les aider à comprendre les principes sous-jacents. Après tout, ils peuvent avoir un passé "old school" comme moi.
la source
Les expressions lambda conduisent à un code moins lisible si les requêtes sont trop longues. Cependant, c'est beaucoup mieux que trop de boucles imbriquées .
C'est mieux avec un mélange des deux .
Écrivez-le en lambda s'il est plus rapide (vous avez besoin d'être rapide) ou plus facile à lire.
la source
Je pense que cela dépend dans la plupart des cas (sauf lorsque vous faites quelque chose de très bizarre) si vous voulez dire "lisible" en tant que personne ayant l’idée de ce qui se passe ou s’ils peuvent facilement trouver tous les petits détails.
Je pense que le lien aide avec le premier, mais souvent (surtout lors du débogage) fait du mal au second.
IMHO quand je regarde le code, je ne suis pas familier avec le premier est énormément plus important que le dernier, donc je le trouve beaucoup plus lisible.
la source
where e.FirstName == "John"
et la traduit en requête SQL! Pour ce faire, il examine l'expression non compilée (mais analysée), car il s'agit d'une comparaison d'une propriété appeléeFirstName
sur une entité persistante, d'une comparaison avec une chaîne, etc. Il se passe beaucoup de choses.Je trouve la syntaxe LINQ intuitive et facile à lire, d’autant plus qu’elles placent le FROM au début, comme il se doit, plutôt qu’au milieu, comme en SQL. Mais les lambdas de l’OMI sont source de confusion et rendent le code plus difficile à lire.
la source
\x -> x * x
) ou F # (fun x -> x * x
)?Je conviens avec vous que la syntaxe Linq n'est pas très différente de celle de T-SQL. Je pense que votre collègue pourrait vraiment s'opposer à ce que des éléments relationnels soient mélangés, dans lesquels son code OO agréable et brillant. Par ailleurs, la programmation fonctionnelle demande un peu d’habitude et une volonté de s’y habituer.
la source
Ça dépend. De toute évidence, T-SQL fournit uniquement des solutions relationnelles à la base de données. De toute évidence, LINQ fournit uniquement des solutions d’OO.
Toutefois; "Plus déroutant que T-SQL?" - est discuté / demandé dans la question initiale. Cela implique clairement certaines caractéristiques qu’aucune des réponses existantes n’a abordées, accusant au contraire le critique (visiblement familier avec SQL) d’être bloqué dans le passé.
Donc, bien que j'apprécie LINQ pour certaines qualités et que je ne désapprouve pas beaucoup les réponses existantes, je pense que le contrepoint mérite d'être représenté:
Des années après la familiarisation avec LINQ, l'exécution de certains types d'opérations de groupe, les jointures externes et les non-équijointures, l'utilisation de clés composites et d'autres opérations dans LINQ me font encore grincer des dents. (Surtout lorsque vous ciblez un back-end relationnel avec des questions sensibles à la performance.)
Si vous pensez que c'est intuitif, vous aurez plus de pouvoir. ;)
la source
Il y a probablement une raison pour laquelle Linq craint, essayez juste de faire des exemples du monde réel, au lieu de ces exemples classiques.
essayez de montrer cette fonction dans linqlamdathings et vous verrez que toute la beauté a disparu, alors que la manière classique reste lisible. Sans parler des problèmes d'exécution différée et de la définition de points d'arrêt.
La vérité est que LinqLambdaThings est très utile dans peu de cas et on ne pense pas qu'il remplace toute l'orientation astucieuse des objets que vous n'avez jamais comprise
la source
source.Where(c => c.IsVip && c.FirstName == "Aaron" || c.SecondName == "Aaron").Take(maxCount).OrderBy(d => d.LastName);
c’est difficile à lire mais j’ai peut-être commis une erreur;)