Wie erzwinge ich, dass meine Lambda-Ausdrücke früh ausgewertet werden? Fix Lambda Ausdruck Verrücktheit?

8

Ich habe den folgenden C # -Code geschrieben:

%Vor%

Dieser Code soll ein Wörterbuch mit meinen "region ids" als Schlüssel und Listen von "location ids" als Werte erstellen.

Was aber tatsächlich passiert, ist, dass ich ein Wörterbuch mit den "region ids" als Schlüssel erhalte, aber der Wert für jeden Schlüssel ist identisch: es ist die Liste der Orte für die letzte Regions-ID in regionIds!

Es sieht so aus, als wäre dies ein Produkt der Auswertung von Lambda-Ausdrücken. Ich kann das korrekte Ergebnis erhalten, indem ich die Liste der Standort-IDs auf ein Array umwandele, aber das fühlt sich an wie ein Kludscher.

Was ist eine gute Vorgehensweise für den Umgang mit dieser Situation?

    
Daniel Allen Langdon 22.07.2011, 18:37
quelle

4 Antworten

10

Sie verwenden LINQ. Sie müssen eine eifrige Operation durchführen, um die Auswahl durchzuführen. ToList () ist ein guter Operator, um das zu tun. Liste ist generisch und kann IEnumberable direkt zugewiesen werden.

Wenn Sie LINQ verwenden, wird standardmäßig faul ausgewertet. ToList / eager-Vorgänge erzwingen die Auswahl. Bevor Sie einen dieser Operatoren verwenden, wird die Aktion nicht ausgeführt. Es ist, als würde man SQL in ADO.NET ausführen. Wenn Sie die Anweisung "Select * from users" haben, die die Abfrage nicht wirklich durchführt, bis Sie zusätzliche Dinge tun. Die ToList bewirkt, dass die Auswahl ausgeführt wird.

    
m4tt1mus 22.07.2011, 18:40
quelle
8

Sie schließen die Variable, nicht den Wert.

Erstellen Sie eine lokale Kopie der Variablen, so dass Sie stattdessen den aktuellen Wert aus der foreach-Schleife erfassen:

%Vor%

Dann lies das:

Ссылка

edit - Das Erzwingen einer eifrigen Auswertung würde auch funktionieren, wie andere es vorgeschlagen haben, aber die meiste Zeit sind eifrige Bewertungen viel langsamer.

    
asawyer 22.07.2011 18:40
quelle
4

Rufen Sie ToList() oder ToArray() nach Select(...) auf. Somit wird die gesamte Sammlung genau dort bewertet.

    
Ivan Danilov 22.07.2011 18:39
quelle
0
___ answer6794580 ___

Rufen Sie %code% oder %code% nach %code% auf. Somit wird die gesamte Sammlung genau dort bewertet.

    
___ answer6794593 ___

Sie verwenden LINQ. Sie müssen eine eifrige Operation durchführen, um die Auswahl durchzuführen. ToList () ist ein guter Operator, um das zu tun. Liste ist generisch und kann IEnumberable direkt zugewiesen werden.

Wenn Sie LINQ verwenden, wird standardmäßig faul ausgewertet. ToList / eager-Vorgänge erzwingen die Auswahl. Bevor Sie einen dieser Operatoren verwenden, wird die Aktion nicht ausgeführt. Es ist, als würde man SQL in ADO.NET ausführen. Wenn Sie die Anweisung "Select * from users" haben, die die Abfrage nicht wirklich durchführt, bis Sie zusätzliche Dinge tun. Die ToList bewirkt, dass die Auswahl ausgeführt wird.

    
___ qstntxt ___

Ich habe den folgenden C # -Code geschrieben:

%Vor%

Dieser Code soll ein Wörterbuch mit meinen "region ids" als Schlüssel und Listen von "location ids" als Werte erstellen.

Was aber tatsächlich passiert, ist, dass ich ein Wörterbuch mit den "region ids" als Schlüssel erhalte, aber der Wert für jeden Schlüssel ist identisch: es ist die Liste der Orte für die letzte Regions-ID in regionIds!

Es sieht so aus, als wäre dies ein Produkt der Auswertung von Lambda-Ausdrücken. Ich kann das korrekte Ergebnis erhalten, indem ich die Liste der Standort-IDs auf ein Array umwandele, aber das fühlt sich an wie ein Kludscher.

Was ist eine gute Vorgehensweise für den Umgang mit dieser Situation?

    
___ tag123net ___ Das .NET-Framework ist ein Software-Framework, das hauptsächlich für das Microsoft Windows-Betriebssystem entwickelt wurde. Es enthält eine Implementierung der Basisklassenbibliothek, Common Language Runtime (allgemein als CLR bezeichnet), Common Type System (allgemein als CTS bezeichnet) und Dynamic Language Runtime. Es unterstützt viele Programmiersprachen, einschließlich C #, VB.NET, F # und C ++ / CLI. NICHT für Fragen zu .NET Core verwenden. ___ tag123linq ___ Die Language Integrated Query (LINQ) ist eine Microsoft .NET Framework-Komponente, die native Datenabfragefunktionen zu .NET-Sprachen hinzufügt. Bitte denken Sie bei Bedarf daran, ausführlichere Tags zu verwenden, zum Beispiel [linq-to-sql], [linq-to-entities] / [entity-framework] oder [plinq] ___ tag123lambda ___ Anonyme Funktionen oder Closures in Programmiersprachen wie Lisp, C #, C ++, Lua, Python, Ruby, Javascript oder Java. (Auch Lambda-Ausdruck.) ___ tag123c ___ C # (sprich "Cis") ist eine objektorientierte Programmiersprache auf hohem Niveau, die für die Erstellung einer Vielzahl von Anwendungen entwickelt wurde, die auf dem .NET Framework (oder .NET Core) ausgeführt werden. C # ist einfach, leistungsfähig, typsicher und objektorientiert. ___ antwort12884119 ___

Eigentlich handelt es sich um eine Nachschlage-Erstellung, die einfacher mit der Standard-LINQ-Gruppen-Verknüpfung erreicht werden kann:

%Vor%

In diesem Fall werden alle Orte gleichzeitig heruntergeladen und im Speicher gruppiert. Diese Abfrage wird auch nicht ausgeführt, bis Sie versuchen, auf Ergebnisse zuzugreifen, oder bis Sie sie in das Wörterbuch konvertieren:

%Vor%     
___ answer6794585 ___

Sie schließen die Variable, nicht den Wert.

Erstellen Sie eine lokale Kopie der Variablen, so dass Sie stattdessen den aktuellen Wert aus der foreach-Schleife erfassen:

%Vor%

Dann lies das:

Ссылка

edit - Das Erzwingen einer eifrigen Auswertung würde auch funktionieren, wie andere es vorgeschlagen haben, aber die meiste Zeit sind eifrige Bewertungen viel langsamer.

    
___ qstnhdr ___ Wie erzwinge ich, dass meine Lambda-Ausdrücke früh ausgewertet werden? Fix Lambda Ausdruck Verrücktheit? ___
Sergey Berezovskiy 14.10.2012 16:20
quelle

Tags und Links