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中的程序集,看看编译器是否正在重新排序任何操作,但它似乎没有.这是如何运作的?
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)
| 归档时间: |
|
| 查看次数: |
2347 次 |
| 最近记录: |