Für welche Problemdomäne ist LINQ gemacht?

12

Jedes Mal, wenn ich eine Frage im Stapelüberlauf in C # sehe, werden mindestens ein oder zwei Antworten angezeigt, die ein Problem mit LINQ lösen. Normalerweise scheinen Leute mit sehr hohem Ansehen LINQ-ähnliche Profis zu verwenden.

Meine Frage ist also, für welche Problemdomäne soll LINQ verwendet werden?

Auch zu den Randnotizen: Gibt es irgendwelche Zwecke, bei denen es vermieden werden sollte? Beeinflusst die Größe des Datasets die Leistung von LINQ-Abfragen?

user1816120
quelle
1
LINQ dient zum Abfragen von Objektgraphen. Es handelt sich um eine sprachintegrierte Abfrage, mit der Sie Sammlungen abfragen und bearbeiten können.
Oded
1
es ist wahrscheinlich eine abschließbare Frage, wie es aussieht, könnte eine gute Frage dahinter stecken, für welche Probleme Linq gut geeignet ist
jk.
1
Linq ist deklarativ. Sie geben an, was Sie wollen, ohne anzugeben, wie es gemacht wird. Für linq bedeutet dies, dass Sie mithilfe von Abfragen angeben können, was Sie möchten. Deklarativer Code kann bei einigen Problemen kürzer und verständlicher sein.
mike30

Antworten:

16

LINQ wurde in erster Linie entwickelt, um reine funktionale Abfragen und Transformationen von Datensequenzen zu ermöglichen (Sie werden feststellen, dass alle LINQ-Erweiterungen Func-Delegates, aber keine Action-Delegates aufnehmen). Folglich ist der häufigste Fall einer Schleife, die nicht sehr gut zu LINQ passt, eine, bei der es um nicht reine funktionale Nebenwirkungen geht, z

foreach(var x in list) Console.WriteLine(x);

Um LINQ besser nutzen zu können, üben Sie es einfach.

Überlegen Sie sich, wann immer Sie eine foroder eine foreachSchleife schreiben möchten, um etwas mit einer Sammlung zu tun, ob sie zu LINQ passt (dh nicht nur eine Aktion oder einen Nebeneffekt auf die Elemente ausübt), und zwingen Sie sich dann zum Schreiben es mit LINQ.

Sie können die foreachVersion auch zuerst schreiben und dann in eine LINQ-Version umschreiben.

Wie Svick betont, sollte es in LINQ darum gehen, Ihr Programm besser lesbar zu machen. Dies ist normalerweise gut, da es eher die Absicht des Codes als den Mechanismus betont. Wenn Sie jedoch feststellen, dass Ihre Abfragen nicht lesbarer sind als eine einfache Schleife, können Sie sich gerne an die Schleife halten.

Wenn Sie Übungen zum Üben benötigen, lassen sich die meisten funktionalen Programmierübungen gut auf LINQ abbilden, z. B. 99 Probleme (insbesondere die ersten 20 oder so) oder Project Euler .

jk.
quelle
Möglicherweise muss ich diese Frage jetzt löschen. Der Moderator merkte an, dass es nicht für die Community geeignet ist. Wenn Sie sich anders fühlen, sagen Sie es mir bitte.
user1816120
1
Ich würde hinzufügen, dass, wenn Sie es in LINQ umschreiben und das Original noch besser lesbar ist, Sie das Original behalten und die LINQ-Version entfernen. Manchmal fügt LINQ einfach nichts hinzu.
Svick
@svick in der Theorie ja, ich bin mir nicht sicher, ob ich mir Beispiele dafür vorstellen kann;)
jk.
1
@jk. Zum Beispiel bietet ReSharper manchmal an, meine Schleife mit LINQ zu konvertieren Aggregate(). Ich denke die meiste Zeit ist die Schleife besser lesbar.
Svick
@svick ist wahrscheinlich ein Problem, an das Sie gewöhnt sind, obwohl ich zugeben werde, dass aggregate ein unbeholfener Name für fold
jk ist.
1

Um die bearbeitete Frage zu beantworten: Kurz gesagt, es ist nützlich, LINQ immer dann zu verwenden, wenn Sie die "Abfrage" -Funktionalität implementieren müssen (wofür das Q in LINQ steht). Das Definieren einer genauen Domäne ist schwierig, vereinfacht jedoch eine Vielzahl von Aufgaben im Zusammenhang mit dem Extrahieren und Bearbeiten von Daten aus Sammlungen erheblich.

Um es kurz zu machen: Viele Abfragefunktionen wurden direkt in die Sprache (oder vielmehr in die verschiedenen LINQ-Implementierer) integriert, sodass Dinge wie Aggregationen, Ordnen, Gruppieren, Filtern, Projektionen, Verknüpfungen (und vieles mehr) behandelt werden Sie. Die LINQ-basierten Lösungen sind in der Regel auch viel kürzer als wenn Sie sie "von Hand" implementieren und ihre Absichten weitaus besser kommunizieren würden.

Ein einfaches Beispiel, das oft hilft, die Leistungsfähigkeit von LINQ zu vermitteln, ist die Anzeige des Inhalts eines Verzeichnisses, gruppiert nach Erweiterung. Führen Sie eine typische Imperativimplementierung in Ihrem Kopf durch - es werden bereits zu Beginn viele Implementierungsdetails angezeigt. Vielleicht werden wir a verwenden, Dictionary<String, List<String>>um die Dateien nach Erweiterung zu indizieren. Natürlich müssen wir prüfen, ob ein Schlüssel bereits vorhanden ist, eine Liste instanziieren, hinzufügen usw. Es könnte ungefähr so ​​aussehen:

Dictionary<string, List<string>> fileGroups = new Dictionary<string, List<string>>();

foreach (string file in Directory.GetFiles(Environment.CurrentDirectory))
{
    string extension = Path.GetExtension(file).ToLower();

    if (!fileGroups.ContainsKey(extension))
    {
        fileGroups[extension] = new List<string>();
    }

    fileGroups[extension].Add(file);
}

Betrachten Sie das LINQ-Äquivalent:

var query = from file in Directory.GetFiles(Environment.CurrentDirectory)
            group file by Path.GetExtension(file).ToLower();

Beachten Sie, dass die Abfrage selbst nur aus 2 Zeilen besteht, was sicherlich kürzer ist als jede zwingende Lösung, die wir uns hätten ausdenken können. Es ist auch ziemlich lesbar; Das Signal-Rausch-Verhältnis ist höher als bei der ersten Lösung. Für diejenigen, die neu in LINQ sind, würden Sie die Ergebnisse dieser Abfrage wie folgt ausgeben:

foreach (var fileGroup in query)
{
    Console.WriteLine(String.Format("*** Files with extension: {0}", group.Key));

    foreach (string file in fileGroup)
    {
        Console.WriteLine(file);
    }
}

Bei komplexeren Beispielen werden die Unterschiede normalerweise noch größer (z. B. einfach nach mehreren Feldern gruppieren). Zusammenfassend lässt sich sagen, dass LINQ viele "alltägliche" Datenabfrageprobleme auf eine Art und Weise löst, die oft kürzer und selbsterklärender ist. Dies ist mit geringen Kosten für das Erlernen der Syntax und der Technologie verbunden, aber die Vorteile überwiegen bei weitem die Nachteile.

Daniel B
quelle
Klassifizierst du map oder fold als "abfragen"? Ich weiß es nicht wirklich, aber ich denke, ich könnte es vielleicht sehen. Normalerweise würde ich mir ein Aggregat als Ergebnis einer Berechnung vorstellen, keine "Abfrage"
Jimmy Hoffa
@ JimmyHoffa Ich beziehe mich hauptsächlich auf die Anwendung der Berechnung auf die zugrunde liegende Sammlung, nicht unbedingt auf die Berechnung selbst. Aber es gibt wahrscheinlich klaffende Löcher in meiner Analogie, sie soll eher illustrativ als 100% korrekt sein.
Daniel B
@JimmyHoffa nein, aber dann bin ich mir nicht sicher, ob es eine strikte Definition gibt, mit was eine Abfrage beginnen soll
jk.
0

Im Laufe der Zeit wurden verschiedene Sprachen für die verschiedenen Arten von Datenquellen entwickelt, beispielsweise SQL für relationale Datenbanken und XQuery für XML. Daher mussten Entwickler für jeden Datenquellentyp oder jedes Datenformat, das sie unterstützen müssen, eine neue Abfragesprache lernen. LINQ vereinfacht diese Situation, indem es ein konsistentes Modell für die Arbeit mit Daten über verschiedene Arten von Datenquellen und -formaten hinweg anbietet. In einer LINQ-Abfrage arbeiten Sie immer mit Objekten. Weitere Informationen finden Sie unter http://msdn.microsoft.com/en-us/library/bb397906.aspx

Rabbil
quelle
Genau LINQ ist eine Abstraktions-API für die Arbeit mit Sammlungen. Einige wichtige Vorteile: Mit C # erhalten Sie STATIC! Überprüfung Ihrer Abfragen und Transformationen
AndreasScheinert