2016-01-10 14 views
5

w app konsoli, od statycznej metody w głównym programie klasy wzywam:Dlaczego nie sposób wykonać od wewnątrz LINQ Gdzie metoda

internal class Module 
{ 
    public bool EnsureModuleLocalInstall() 
    { 
     if (CheckModuleUpToDateLocal()) 
      return true; 
     else if (DownloadComponentData()) 
      if(InstallModuleLocal()) 
       return true; 

     return false; 
    } 
} 

var availableModules = new List<Module>(); 
... // Add several 'Modules' to list 
var installed = availableModules.Where(m => m.EnsureModuleLocalInstall()); 

mam zarówno ustawić break-punkt, a również sprawdził oczekiwany wynik (moduł zainstalowany lokalnie), ale ze wszystkich wskazań metoda "CheckModuleLocalInstall" nie jest wykonywana.

Czy brakuje mi czegoś oczywistego, czy też oczekuję zbyt wiele od metody LINQ "Gdzie" i czy powinienem używać LINQ ForEach?

+7

Rozumiesz [wykonanie odroczonej] (http://blogs.msdn.com/b/charlie/archive/2007/12 /09/deferred-execution.aspx)? –

+0

Zasadniczo LINQ nie nadaje się do definiowania i uruchamiania zapytań z efektami ubocznymi. Nie dziwi, że oczekiwano wywołania metody, ponieważ ** zdefiniowałeś zapytanie. –

+0

Tak, i dziękuję. Żenujące- wszystko, co musiałem zrobić, to dodać ToList(). – Pricey

Odpowiedz

3

Metoda Where jest zaimplementowana przy użyciu deferred execution, więc kwerenda nie zostanie faktycznie uruchomiona, dopóki nie zostanie wykonana iteracja wyniku. Najprostszym sposobem, aby uzyskać listę zainstalowanych modułów jest wywołanie ToList na wartości zwracanej zapytanie:

var installed = availableModules.Where(m => m.EnsureModuleLocalInstall()).ToList(); 
+0

Dzięki Sam, tak jak zauważył Jesse Good, został odroczony i nigdy nie został stracony. – Pricey

3

większości metod LINQ (jak metody Where) powróci do was implementację IEnumerable<T> który nie zawiera wynik kwerendy, ale zamiast tego zawiera wszystkie informacje niezbędne do wykonania kwerendy. Zapytanie zostanie wykonane tylko po rozpoczęciu wyliczania wartości IEnumerable<T>. Nazywa się to Odroczonym Wykonaniem.

Jednym ze sposobów, aby wyliczyć IEnumerable<T> jest powołać ToList takiego:

var installed = availableModules.Where(m => m.EnsureModuleLocalInstall()).ToList(); 
+1

Odroczone wykonanie jest synonimem ** Leniwa ocena ** lub lenistwo. W kontekście obliczeniowym jest on również nazywany obliczeniami symbolicznymi –