gpt4 book ai didi

c# - 什么时候枚举集合(IEnumerable)

转载 作者:太空宇宙 更新时间:2023-11-03 21:36:42 26 4
gpt4 key购买 nike

最近,我遇到了一个奇怪的问题,我有一个方法生成一个 IEnumerable对象的集合。此方法包含四个 yield return返回四个对象的语句。我将结果分配给变量 results使用 var关键字。

var result = GenerateCollection().ToList();

这实际上意味着:List<MyType> result = GenerateCollection() .

我对这个集合的元素做了一个简单的循环。令我惊讶的是,每次调用列表时都会重新枚举集合(对于每个 result[i] )。后来我用了result LINQ 查询中的集合由于集合的不断重新枚举而在性能方面产生了一些不好的结果。

我通过转换为数组而不是列表解决了这个问题。

这让我现在想知道什么时候枚举集合?哪些方法调用使集合重新枚举?

编辑:GenerateCollection()方法看起来与此类似:

public static IEnumerable<MyType> GenerateCollection()
{
var array = data.AsParallel(); //data is a simple collection of sublists of strings
yield return new MyType("a", array.Where(x => x.Sublist.Count(y => y == 'a') == 0));
yield return new MyType("b", array.Where(x => x.Sublist.Count(y => y == 'b') == 0));
yield return new MyType("c", array.Where(x => x.Sublist.Count(y => y == 'c') == 0));
yield return new MyType("d", array.Where(x => x.Sublist.Count(y => y == 'd') == 0));
}

最佳答案

您正在生成内部具有查询的对象 - 它不是一些 array 值序列 - 它的迭代器对象在您将它们传递给 MyType 的构造函数时不会执行.当您创建 MyType 对象列表时

var result = GenerateCollection().ToList();

所有 MyType 实例都被生成并保存到列表中,但是如果您没有在 MyType 构造函数中执行迭代器,则不会执行查询。甚至更多 - 如果您调用一些执行查询的运算符,它们将每次再次执行,例如

result[i].ArrayIterator.Count(); // first execution
foreach(var item in result[i].ArrayIterator) // second execution
// ...

如果将查询执行的结果传递给 MyType 构造函数,则可以修复它:

yield return new MyType("a", array.Where(x => !x.Sublist.Contains('a')).ToList())

现在您传递的是项目列表而不是迭代器(您也可以使用 ToArray())。当您生成 MyType 实例时执行查询,并且不会再次执行。

关于c# - 什么时候枚举集合(IEnumerable),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21369862/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com