LINQ延迟求值导致数组迭代器问题
本文关键字:数组 迭代器 问题 延迟 LINQ | 更新日期: 2023-09-27 18:10:42
我有一个包含四个EnumerableRowCollections的类,它们都指向同一个数据表。主要的一个将需要在不同的类实例中过滤出其他三个的不同组合。因为其中三个是相关的,所以我把它们放在一个数组中。
EnumerableRowCollection<DataRow> valid;
EnumerableRowCollection<DataRow>[] pending;
所有这些集合都是在类的构造函数中定义的,但是由于LINQ的惰性求值,它们会在之后求值。
我还有一个布尔值数组,用于确定从"有效"集合中过滤出哪些"未决"集合。它们也在构造函数中赋值,并且永远不会更改。
Boolean[] pendingIsValid;
"valid"集合被这样过滤:
for (var i = 0; i < pending.Length; i++)
if (pendingIsValid[i] && pending[i].Count() > 0)
valid = valid.Where(r => !pending[i].Contains(r));
这也发生在构造函数中,但是Where子句按照预期惰性地求值。
这在大多数情况下都是有效的,但是,在少数情况下,当收集求值发生时,我得到了一个奇怪的异常。
我得到一个indexoutorange,因为在上面的for循环中,局部迭代器变量I被设置为3。
问题:
- 我可以使"在哪里"评估数组索引器(或其他子表达式)非惰性?
- 迭代器是如何被加到3的?这个惰性求值算作"重新进入"循环吗?
- ! ? ! ?
改成:
for (var i = 0; i < pending.Length; i++)
if (pendingIsValid[i] && pending[i].Count() > 0)
{
var j = i;
valid = valid.Where(r => !pending[j].Contains(r));
}
对于问题#1 -您可以通过在末尾添加. tolist()来使它不懒惰。但是,通过上面的修复,您可以使它保持惰性。
看一下这个:c#循环中捕获的变量的解释
很好,罗伯。当我在等待回复的时候,我也想到了这个,但是你的看起来更干净一些。
for (var i = 0; i < pending.Length; i++) {
var p = pending[i];
if (pendingIsValid[i] && p.Count() > 0)
valid = valid.Where(r => !p.Contains(r));
}