LINQ 产生所有元素

LINQ yield all elements

当我想得到一个 IEnumerable 到 eagrly materialize/yield 它的所有结果时,我通常使用 ToList() 像这样:

var myList= new List<int>();
IEnumerable<int> myXs = myList.Select(item => item.x).ToList();

我通常在锁定返回 Linq 查询结果的方法时这样做。

在这种情况下,我实际上对集合变成列表不感兴趣,而且我通常不想知道它的类型。我只是使用 ToList() 因为它的副作用 - 产生所有元素。

例如,如果我将类型从 List 更改为 Array,我还必须记住将 ToList() 更改为 ToArray() 或遭受一些性能影响。

我可以 foreach( var e in myList ) { } 但我不确定这是否会在某个时候得到优化?

我正在寻找类似 myList.Select(item => item.x).yield()

的内容

最好的方法是什么?有没有一种方法可以简单地告诉 Linq 结果产生比 ToList 更好的所有元素?

如果重点只是练习列表,不想构造或分配任何类型的数组,您可以使用 Last(),它将简单地遍历所有元素,直到它得到到最后一个(参见 source)。

如果您真的对结果感兴趣,在大多数情况下您应该 use ToList() 而不要想太多。

如果您想稍后检索结果,就无法避免分配某种存储空间。没有没有具体类型的神奇 IEnumerable<T> 容器;你必须选择一个,ToList() 是最明显的选择,开销很低。

如果您不想等待它完成,请不要忘记 ToListAsync()

仅供参考,因为这可能就是问题所在

您不必在一行中编写 LINQ 操作,您可以进一步扩展它:

例如:

var myList = new List<T>();
var result = myList.Select(x => x.Foo).Where(x => x.City == "Vienna").Where(x => x.Big == true).ToList();

可以重写为:

var myList = new List<T>();

//get an IEnumerable<Foo>
var foos = myList.Select(x => x.Foo);

//get an IEnumerable<Foo> which is filtered by the City Vienna
var foosByCity = foos.Where(x => x.City == "Vienna");

//get an IEnumerable<Foo> which is futher filtered by Big == true
var foosByCityByBig = foosByCity.Where(x => x.Big == true);

//now you could call to list on the last IEnumerable, but you dont have to
var result = foosByCityByBig.ToList();

所以无论你的真正目标是什么,也许你可以改变你的路线

var myList= new List<int>();
IEnumerable<int> myXs = myList.Select(item => item.x).ToList();

为此:

var myList= new List<int>();
IEnumerable<int> myXs = myList.Select(item => item.x);

并继续 myXs 作为 IEnumerable<int> 的工作。