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。


问题:

  1. 我可以使"在哪里"评估数组索引器(或其他子表达式)非惰性?
  2. 迭代器是如何被加到3的?这个惰性求值算作"重新进入"循环吗?
  3. ! ? ! ?

LINQ延迟求值导致数组迭代器问题

改成:

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));
}