Мих*_*оев -4 c# linq ienumerable
文件包含一些字符串,如:
abc 4 2
def 1 1 1
Gh 0
有一些LINQ功能,这个功能的细节并不那么重要
IEnumerable<List<int>> F() {
return File.ReadLines("input.txt")
.Select(a => a.Split(' ').Skip(1).Select(int.Parse).ToList())
.Where(a => a.Count >= 2)
.Take(3).OrderBy(a => a.Sum())
.Select(a => { Console.Write(a[0]); return a; });
}
Run Code Online (Sandbox Code Playgroud)
此功能不会向控制台输出任何内容.为什么?
您必须具体化序列才能使其运行:
IEnumerable<List<int>> F() {
return File.ReadLines("input.txt")
.Select(a => a.Split(' ').Skip(1).Select(int.Parse).ToList())
.Where(a => a.Count >= 2)
.Take(3).OrderBy(a => a.Sum())
.Select(a => { Console.Write(a[0]); return a; })
.ToList();
}
Run Code Online (Sandbox Code Playgroud)
在相关的说明中,建议不要在LINQ表达式中引起副作用.如果此代码用于调试目的,那么它没关系.但是如果您打算将其保留以备将来使用,那么我建议您Console.Write从LINQ表达式中删除它.
我们不应该在表达式中引起副作用的原因是大多数LINQ运算符都是惰性求值的.反过来,这样做是为了通过仅评估有效请求的序列的那些元素来提高性能.现在,如果评估会产生副作用,那么如果对同一个懒惰序列进行多次评估,这些影响可能会发生几次 - 这可能不是您想要发生的事情.
这是延期执行。
只有当您实际枚举结果时,您才会执行该语句。
例如:
IEnumerable<List<int>> F() {
return File.ReadLines("input.txt")
.Select(a => a.Split(' ').Skip(1).Select(int.Parse).ToList())
.Where(a => a.Count >= 2)
.Take(3).OrderBy(a => a.Sum())
.Select(a => { Console.Write(a[0]); return a; });
}
void Main()
{
foreach(var r in F()) //the result is enumerated and will execute the select
{
//do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
查看其他问题:
如果您调用 ,也会发生同样的事情F().ToList()。
如果枚举本身需要大量资源,则此行为特别有用。有时,底层框架能够在后期优化枚举。
例如,如果您调用以下代码,智能交互器或表达式构建器将能够优化事物:
F().Where(c => ....)
Run Code Online (Sandbox Code Playgroud)