7
votes

Retrouver vs où

J'ai un iEnumerable que je voulais filtrer en fonction d'un prédicat LINQ. J'ai essayé d'utiliser sur le ienumerable comme je le fais normalement, mais cette fois je suis tombé sur quelque chose d'intéressant. Lorsque vous appelez où sur le iEnumerable , avec le prédicat, je reçois une liste vide en retour. Je sais que cela doit produire une liste avec deux articles dedans. Si je dispose plutôt d'utiliser retranchée , avec le même prédicat, il produit ensuite le résultat correct.

Quelqu'un peut-il m'expliquer, pourquoi cela se passe-t-il? J'ai toujours pensé que était une sorte de version paresseuse de Restacletall , qui a également renvoyé un ienumerable au lieu d'une liste . Il doit y avoir plus que cela? (J'ai fait des recherches, mais en vain.)

code: xxx


4 commentaires

Liste .Findall renvoie une liste alors que retourne un ienumerable . Mais utilise une exécution différée, vous ne l'obtenez donc que lorsque vous matérialisez it, f.e. avec tolist .


Pourquoi n'avez-vous pas posté cela comme une réponse? :) Meilleure explication que la seule réponse ici, qui a été publiée plus tard que votre commentaire.


Même si votre commentaire a répondu à la question, une réponse a été publiée, ce qui répond cela plus approfondi que toutes les réponses sur la question liée.


Que je suis au courant de :)


3 Réponses :


1
votes

Vous pouvez trouver votre réponse ici: LINQ, où () vs Findall () . Essentiellement si vous appelez .tolist () sur votre "où", ils seraient les mêmes.

Vous pouvez en trouver plus sur les différences entre l'exécution différée et immédiate: HTTPS: //code.msdn.microsoft.com/linq-query-execution-ce0d3b95


1 commentaires

Je sais que ce que vous déclarez est probablement une explication simplifiée des différences entre les deux, mais je reçois l'idée. Merci!



2
votes

Ma meilleure hypothèse serait que quelque chose se passe entre appeler où, qui crée un énumérateur et le lieu de votre code où les résultats sont réellement utilisés (c'est-à-dire lorsque le courant MOVENEXT et (get_) de cet énumérateur est réellement appelé, par exemple de TOLIST ).


1 commentaires

Le problème ici était que je n'ai pas appelé .tolist () lorsque vous utilisez où () sur l'iSenumérable, alors inspectez-le montrer une liste vide.



1
votes

Oui, où est une version paresseuse de Findall. Findallyl () est une fonction sur le type de liste, ce n'est pas une méthode d'extension LINQ comme si. La méthode Findall sur la liste, qui est une méthode d'instance qui renvoie une nouvelle liste avec le même type d'élément. WASTALL ne peut être utilisé que sur les instances de la liste, tandis que les méthodes d'extension LINQ fonctionnent sur n'importe quel type qui implémente iEnumerable.

La principale différence (en plus de ce qu'elles sont implémentées sur: iEnumerable vs. List) est que, où implémente l'exécution différée, où elle ne fait pas la recherche avant d'en avoir besoin, (en l'utilisant dans une boucle foreach par exemple ). WASTALL est une méthode d'exécution immédiate.

Je vous référerai à une structure de données appelée arborescence d'expression pour comprendre l'exécution différée, vous n'avez besoin que d'une saisie qu'une arborescence d'expression est une structure de données comme une liste ou une file d'attente. Il détient une requête LINQ à SQL et non les résultats de la requête, mais les éléments réels de la requête elle-même.

pour comprendre le travaillant, nous avons besoin de voir que si nous écrivons Un code xxx

requête ne s'exécute pas ici alors qu'il s'exécutent dans la boucle de Foreach

pour comprendre linq et exécution différée


0 commentaires