For 循环在完成后重复并返回 ArgumentOutOfRangeException

For loop is repeating after finish and returning ArgumentOutOfRangeException

我将 foreach 传递给 for 以提高性能。但是,我认为我的 for 很好,但是在运行之后,我不知道为什么它上次重复了 1 次(即使它与句子不对应)并且它抛出错误,因为 "i" 不存在在该列表中。

我搜索了一下,没有人遇到这个错误,所以我很好奇。我的意思是条件很好并且工作正常 "the first time" 但是随后,它不知从哪里再次运行并中断。

这可能是因为我正在为 list1 执行 ToList()?因为调用数据库 returns 一个 IEnnumerable 并且我不能将它用于 For 循环。

    var list1 = GetData1FromDB().ToList();
        var list2 = GetData2FromDB();

        for (int i = 0; i <= list1.Count() - 1; i++)
        {
            var data2 = list2.Where(x => x.Id == list1[i].Id);
            list1[i].Details = data2;
            result.data1.Add(list1[i]);
        }

我怀疑问题是延迟执行/懒惰评估 caused by LINQ(请参阅 备注 部分)。当您这样做时:

var data2 = list2.Where(x => x.Id == list1[i].Id);
list1[i].Details = data2;

您已经创建了一个 IEnumerable,它知道 list2 中的 return 个元素,其中 x.Id == list1[i].Id。但它还没有真正执行该逻辑 - 它只是记得 "how" 执行它,包括它需要引用哪些变量。

它将在稍后执行,当某些东西实际尝试枚举它时。问题是后来,i变量的值变成了超出范围的值(因为ifor循环递增,直到超出范围)。

您可以通过在末尾添加 .ToList() 来强制 IEnumerable 立即执行。这将枚举它并将内容放入列表中。

有关 lambda 捕获变量的更多说明,请参阅:https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/closing-over-the-loop-variable-considered-harmful/