2012-04-09 14 views
0

NehmenVerständnis der Verarbeitungspipeline

 var query = Process.GetProcesses() 
          .OrderBy(p => p.WorkingSet64) 
          .ThenByDescending(p => p.Threads.Count); 
          .Where(p => p.ProcessName.Length < 9); 

Es funktioniert gut. Nehmen Sie

 var query = Process.GetProcesses() 
          .OrderBy(p => p.WorkingSet64) 
          .ThenByDescending(p => p.Threads.Count); 
          //.Where(p => p.ProcessName.Length < 9); 

     query = query.Where(p => p.ProcessName.Length < 9); 

Dies funktioniert nicht. Ich verstehe nicht, warum die erste Methode funktioniert. In meinen Gedanken sind diese Fragen die gleichen. ThenByDescending gibt IOrderedEnumerable<T> zurück, das an Where() weitergeleitet wird. Die erste Methode sollte nicht funktionieren, da Where nur mit IEnumerable<T> funktioniert. Ach ... es funktioniert.

Wie funktioniert diese Verarbeitung Pipeline-Funktion?

+1

Array implementiert '' und IEnumerable' GetProcesses' eine Reihe von Prozessen gibt http://msdn.microsoft.com/en-us/library/system.array.aspx –

Antwort

8

Der Unterschied ist wegen eines falschen Verständnisses des var Schlüsselwort und LINQ-Abfragen.

var (C# reference)

Verwenden des var Schlüsselwort ist die gleiche wie die gleiche Art wie die rechte Seite der Zuweisung angibt. Es bedeutet nicht, dass Sie der Variablen einen beliebigen Typ zuweisen können.

In LINQ-Abfragen geben die meisten grundlegenden Ausdrücke eine IEnumerable zurück, aber in vielen Fällen geben sie nicht nur eine IEnumerable zurück. Stattdessen geben sie einen Typ zurück, der von IEnumerable erbt.

In diesem Fall tun Sie das Äquivalent von dieser:

IEnumerable<Process> query = Process.GetProcesses() 
          .OrderBy(p => p.WorkingSet64) 
          .ThenByDescending(p => p.Threads.Count); 
          .Where(p => p.ProcessName.Length < 9); 

und

IOrderedEnumerable<Process> query = Process.GetProcesses() 
            .OrderBy(p => p.WorkingSet64) 
            .ThenByDescending(p => p.Threads.Count); 

// Won't work because Where doesn't return an IOrderedEnumerable. 
query = query.Where(p => p.ProcessName.Length < 9); 

Der Grund, dass das erste Schnipsel funktioniert, weil IOrderedEnumerable erbt von IEnumerable, so können Sie es verwenden so wie. Um das Problem im zweiten Beispiel zu beheben, müssen Sie query explizit als IEnumerable<Process> deklarieren.