Ich bin dazu gekommen, LINQ in meiner täglichen Programmierung häufig zu verwenden. Tatsächlich verwende ich selten, wenn überhaupt, eine explizite Schleife. Ich habe jedoch festgestellt, dass ich die SQL-ähnliche Syntax nicht mehr verwende. Ich benutze nur die Erweiterungsfunktionen. Also lieber dann sagen:
from x in y select datatransform where filter
Ich benutze:
x.Where(c => filter).Select(c => datatransform)
Welchen LINQ-Stil bevorzugen Sie und womit fühlen sich andere in Ihrem Team wohl?
c#
coding-style
linq
Erin
quelle
quelle
Antworten:
Ich finde es bedauerlich, dass Microsoft laut MSDN-Dokumentation die Abfragesyntax bevorzugt, da ich sie nie verwende, aber immer die LINQ-Methodensyntax verwende. Ich liebe es, One-Liner-Anfragen nach Herzenslust abzufeuern. Vergleichen Sie:
Zu:
Schneller, weniger Linien, und für meine Augen sieht es sauberer aus. Die Abfragesyntax unterstützt auch nicht alle Standard-LINQ-Operatoren. Eine Beispielabfrage, die ich kürzlich durchgeführt habe, sah ungefähr so aus:
Meines Wissens würde es so aussehen, wenn diese Abfrage mithilfe der Abfragesyntax (soweit möglich) repliziert wird:
Sieht für mich nicht lesbarer aus, und Sie müssen sowieso wissen, wie man Methodensyntax verwendet. Persönlich bin ich sehr verliebt in den deklarativen Stil, den LINQ ermöglicht, und nutze ihn in jeder Situation, in der es überhaupt möglich ist - vielleicht manchmal zu meinem Nachteil. Beispiel: Mit der Methodensyntax kann ich Folgendes tun:
Ich würde mir vorstellen, dass der obige Code für jemanden, der ohne gute Dokumentation in das Projekt einsteigt, schwer zu verstehen ist, und wenn er keinen soliden Hintergrund in LINQ hat, versteht er ihn möglicherweise sowieso nicht. Dennoch bietet die Methodensyntax eine ziemlich leistungsstarke Funktion, um schnell (in Bezug auf Codezeilen) eine Abfrage zu projizieren, um aggregierte Informationen zu mehreren Auflistungen abzurufen, die andernfalls eine Menge langwieriger foreach-Schleifen erfordern würden. In einem solchen Fall ist die Methodensyntax äußerst kompakt für das, was Sie daraus machen. Der Versuch, dies mit der Abfragesyntax zu tun, kann ziemlich schnell unhandlich werden.
quelle
Ich finde die funktionale Syntax für das Auge angenehmer. Die einzige Ausnahme ist, wenn ich mehr als zwei Sätze verbinden muss. Das Join () wird sehr schnell verrückt.
quelle
Ist es jemals zu spät, eine weitere Antwort hinzuzufügen?
Ich habe eine Menge LINQ-to-Objects-Code geschrieben und behaupte, dass es zumindest in diesem Bereich gut ist, beide Syntaxen zu verstehen, um den einfacheren Code zu verwenden - was nicht immer Punktsyntax ist.
Natürlich gibt es Zeiten , in denen Punktsyntax IS der Weg zu gehen - andere haben mehrere dieser Fälle vorgesehen ist ; Ich denke jedoch, dass das Verständnis zu kurz gekommen ist - wenn man so will, mit einem schlechten Ruf. Ich werde daher ein Beispiel bereitstellen, in dem ich Verständnis für nützlich halte.
Hier ist eine Lösung für ein Ziffernersetzungspuzzle: (Lösung, die mit LINQPad geschrieben wurde, aber in einer Konsolen-App eigenständig sein kann)
... welche Ausgänge:
Nicht schlecht, die Logik fließt linear und wir können sehen, dass es eine einzige richtige Lösung gibt. Dieses Rätsel lässt sich leicht von Hand lösen: Die Schlussfolgerung 3>>
N
0 undO
> 4 * N impliziert 8> =O
> = 4. Das bedeutet, dass maximal 10 Fälle von Hand getestet werden können (2 fürN
-by- 5 fürO
). Ich habe mich genug verirrt - dieses Rätsel wird zur Veranschaulichung von LINQ angeboten.Compiler-Transformationen
Der Compiler unternimmt viel, um dies in äquivalente Punktsyntax umzusetzen. Abgesehen davon, dass die üblichen zweiten und nachfolgenden
from
Klauseln inSelectMany
Aufrufe umgewandelt werden , gibt eslet
Klauseln, die zuSelect
Aufrufen mit Projektionen werden und beide transparente Bezeichner verwenden . Wie ich gleich zeigen werde, beeinträchtigt das Benennen dieser Bezeichner in der Punktsyntax die Lesbarkeit dieses Ansatzes.Ich habe einen Trick, um herauszufinden, was der Compiler bei der Übersetzung dieses Codes in Punktsyntax tut. Wenn Sie die beiden obigen Kommentarzeilen auskommentieren und erneut ausführen, erhalten Sie die folgende Ausgabe:
Setzen Sie jeden LINQ-Operator in eine neue Zeile, übersetzen Sie die "unaussprechlichen" Bezeichner in diejenigen, die wir "sprechen" können, ändern Sie die anonymen Typen in ihre vertraute Form und ändern Sie den
AndAlso
Ausdrucksbaumjargon, um&&
die Transformationen anzuzeigen, die der Compiler ausführt, um zu einem Äquivalent zu gelangen in Punktsyntax:Was, wenn Sie ausführen, können Sie überprüfen, dass es wieder ausgibt:
... aber würdest du jemals so einen Code schreiben?
Ich würde wetten, dass die Antwort NONBHN ist (nicht nur Nein, sondern verdammt Nein!) - weil es einfach zu komplex ist. Sicher können Sie sich aussagekräftigere Bezeichnernamen als "temp0" .. "temp3" einfallen lassen, aber der Punkt ist, dass sie dem Code nichts hinzufügen - sie sorgen nicht dafür, dass der Code besser funktioniert, sie tun es nicht Verbessern Sie die Lesbarkeit des Codes, da der Code nur hässlich ist. Wenn Sie dies von Hand tun würden, würden Sie ihn ohne Zweifel ein oder drei Mal durcheinander bringen, bevor Sie es richtig machen. Außerdem ist das Spielen des "Namensspiels" für aussagekräftige Bezeichner schwierig genug, sodass ich die Unterbrechung des Namensspiels begrüße, die mir der Compiler beim Verständnis von Abfragen bereitstellt.
Dieses Rätselbeispiel ist möglicherweise nicht real genug, um von Ihnen ernst genommen zu werden. Es gibt jedoch auch andere Szenarien, in denen das Abfrageverständnis glänzt:
Join
undGroupJoin
: das Scoping von Bereichsvariablen in Abfrageverständnisklauselnjoin
wandelt Fehler, die ansonsten in Punktsyntax kompiliert würden, in Fehler zur Kompilierungszeit in der Verständnissyntax um.from
Klauseln ein : multiple Klauseln,join
&join..into
Klauseln undlet
Klauseln.Ich kenne mehr als eine Werkstatt in meiner Heimatstadt, in der die Syntax des Verstehens verboten ist . Ich denke, das ist schade, da die Syntax des Verständnisses nur ein Werkzeug und noch dazu ein nützliches ist. Ich denke, es ist sehr ähnlich zu sagen: "Es gibt Dinge, die Sie mit einem Schraubenzieher tun können, die Sie nicht mit einem Meißel tun können. Da Sie einen Schraubenzieher als Meißel verwenden können, werden Meißel von nun an auf Anordnung des Königs verboten."
quelle
Mein Rat ist, die Abfrage-Verständnis-Syntax zu verwenden, wenn der gesamte Ausdruck in der Verständnis-Syntax ausgeführt werden kann. Das heißt, ich würde bevorzugen:
zu
Aber ich würde es vorziehen
zu
Ich wünschte, wir hätten uns eine Syntax ausgedacht, die es angenehmer macht, beides zu mischen. So etwas wie:
Aber leider haben wir nicht.
Aber im Grunde ist es eine Frage der Präferenz. Tun Sie das, was für Sie und Ihre Mitarbeiter besser aussieht.
quelle
var londonCustomers = from c in ...; int count = londonCustomers.Count();
SQL-like ist ein guter Anfang. Da es jedoch begrenzt ist (es unterstützt nur die Konstruktionen, die Ihre aktuelle Sprache unterstützt), entscheiden sich Entwickler letztendlich für den Stil von Erweiterungsmethoden.
Ich möchte darauf hinweisen, dass es einige Fälle gibt, die leicht durch SQL-ähnlichen Stil implementiert werden können.
Sie können auch beide Möglichkeiten in einer Abfrage kombinieren.
quelle
Ich neige dazu, die Nicht-Abfragesyntax zu verwenden, es sei denn, ich muss eine Variable auf halbem Weg durch die Abfrage definieren
aber ich schreibe die nicht abfragesyntax gerne
quelle
Ich benutze wegen der Bestellung immer die Erweiterungsfunktionen. Nehmen Sie Ihr einfaches Beispiel - in der SQL haben Sie zuerst select geschrieben - obwohl eigentlich das, was zuerst ausgeführt wurde. Wenn Sie mit den Erweiterungsmethoden schreiben, habe ich viel mehr Kontrolle. Ich bekomme ein Gespür dafür, was angeboten wird, ich schreibe Dinge in der Reihenfolge, in der sie geschehen.
quelle
Mir gefällt auch die Extension-Funktion.
Vielleicht, weil es für mich weniger ein Syntaxsprung ist.
Es fühlt sich auch für das Auge besser lesbar an, insbesondere wenn Sie Frameworks von Drittanbietern verwenden, die über linq api verfügen.
quelle
Hier ist die Heuristik, der ich folge:
Ich denke, dass Lambdas mit Joins unordentlich aussehen und schwer zu lesen sind.
quelle