2012-04-09 95 views
0

採取瞭解處理管道

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

它工作正常。以

 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); 

這是行不通的。我不明白爲什麼第一種方法有效。在我看來,這些查詢是相同的。 ThenByDescending返回IOrderedEnumerable<T>,它被傳入Where()。第一種方法不應該起作用,因爲Where只與IEnumerable<T>一起使用。唉......它確實有效。

這個處理管道是如何工作的?

+1

數組實現'IEnumerable'和'GetProcesses'返回一個進程數組http://msdn.microsoft.com/en-us/library/system.array.aspx – 2012-04-09 21:37:20

回答

8

不同之處在於對var關鍵字和LINQ查詢的誤解。

var (C# reference)

使用var關鍵字是與指定的相同類型作爲分配的右側。這並不意味着您可以將任何類型分配給變量。

在LINQ查詢中,大部分基本表達式都返回IEnumerable,但在很多情況下,它們不會返回IEnumerable。相反,它們返回從IEnumerable繼承的類型。

在這種情況下,你正在做的這相當於:

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

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); 

第一片段成功運作的原因是因爲從IEnumerableIOrderedEnumerable繼承,所以你可以使用它因此。

要解決第二個示例中的問題,您需要明確聲明queryIEnumerable<Process>