In Linq, extension methods like Where return an IEnumerable collection, but sorting methods like OrderBy return an IOrderedEnumerable collection.
So, if you have a query that ends with OrderBy (i.e. returns an IOrderedEnumerable), you can't later append a Where method - the compiler complains about the type being passed into Where.
var query = Process.GetProcesses()
.Where(p => p.ProcessName.Length < 10)
.OrderBy(p => p.Id);
query = query.Where(p => p.ProcessName.Length < 5);
However, if you do it all in one query, it's fine!
var query = Process.GetProcesses()
.Where(p => p.ProcessName.Length < 10)
.OrderBy(p => p.Id)
.Where(p => p.ProcessName.Length < 5);
I've looked at the assembly in Reflector to see if the compiler was re-ordering any of the operations, but it doesn't seem to have. How does this work?
IOrderedEnumerable<T>extendsIEnumerable<T>so you can still use any of the extension methods. The reason your first block of code didn't work is because you had effectively written:That fails because
query.Where(...)only returns anIEnumerable<Process>, which can't be assigned to thequeryvariable. It's not callingWherethat's the problem - it's assigning the result back to the original variable. To demonstrate that, this code will work just fine:Alternatively, you can declare query to be
IEnumerable<T>to start with: