Linq如何在IOrderedEnumerable方法之后使用IEnumerable方法?

Gra*_*ark 3 linq ienumerable iorderedenumerable

在Linq中,扩展方法如Where返回IEnumerable集合,但排序方法如OrderBy返回IOrderedEnumerable集合.

因此,如果您的查询以OrderBy(即返回一个IOrderedEnumerable)结束,则以后不能附加Where方法 - 编译器会抱怨传入的类型Where.

var query = Process.GetProcesses()
            .Where(p => p.ProcessName.Length < 10)
            .OrderBy(p => p.Id);

query = query.Where(p => p.ProcessName.Length < 5);
Run Code Online (Sandbox Code Playgroud)

但是,如果你在一个查询中完成所有操作,那很好!

var query = Process.GetProcesses()
            .Where(p => p.ProcessName.Length < 10)
            .OrderBy(p => p.Id)
            .Where(p => p.ProcessName.Length < 5);
Run Code Online (Sandbox Code Playgroud)

我查看了Reflector中的程序集,看看编译器是否正在重新排序任何操作,但它似乎没有.这是如何运作的?

Jon*_*eet 9

IOrderedEnumerable<T>扩展,IEnumerable<T>因此您仍然可以使用任何扩展方法.你的第一段代码不起作用的原因是因为你有效地写了:

IOrderedEnumerable<Process> query = Process.GetProcesses()
                                           .Where(p => p.ProcessName.Length < 10)
                                           .OrderBy(p => p.Id);

// Fail: can't assign an IEnumerable<Process> into a variable 
// of type IOrderedEnumerable<Process>
query = query.Where(p => p.ProcessName.Length < 5);
Run Code Online (Sandbox Code Playgroud)

这失败了因为query.Where(...)只返回一个IEnumerable<Process>,不能分配给query变量.它并没有称Where这是问题 - 它将结果分配回原始变量.为了证明这一点,这段代码可以正常工作:

var query = Process.GetProcesses()
                   .Where(p => p.ProcessName.Length < 10)
                   .OrderBy(p => p.Id);

// Introduce a new variable instead of trying to reuse the previous one
var query2 = query.Where(p => p.ProcessName.Length < 5);
Run Code Online (Sandbox Code Playgroud)

或者,您可以将查询声明IEnumerable<T>为以:

IEnumerable<Process> query = Process.GetProcesses()
                                    .Where(p => p.ProcessName.Length < 10)
                                    .OrderBy(p => p.Id);

// Fine
query = query.Where(p => p.ProcessName.Length < 5);
Run Code Online (Sandbox Code Playgroud)

  • 第二个不会尝试将`IEnumerable <T>`表达式赋给`IOrderedEnumerable <T>`类型的变量. (5认同)