C# IEnumerable项在使用LINQ之前消失,其中

C# IEnumerable项在使用LINQ之前消失,其中,c#,linq,ienumerable,C#,Linq,Ienumerable,我对编程相当陌生,一直在胡乱编写一些随机函数 我编写了下面的函数,它松散地基于eratosthenes筛工作。但最初,我对UpdatedEnumerable有一个问题 UpdateEndites是一种填充(与我收集的延迟执行有关-在调试模式下“current”为null,但结果视图包含相关项)但是当RemoveWhere应用于oddPrimesAndMultiples时,updatedEntries中的项消失了,尽管我不明白为什么它们仍然应该链接到oddPrimesAndMultiples中的项

我对编程相当陌生,一直在胡乱编写一些随机函数

我编写了下面的函数,它松散地基于eratosthenes筛工作。但最初,我对UpdatedEnumerable有一个问题

UpdateEndites是一种填充(与我收集的延迟执行有关-在调试模式下“current”为null,但结果视图包含相关项)但是当RemoveWhere应用于oddPrimesAndMultiples时,updatedEntries中的项消失了,尽管我不明白为什么它们仍然应该链接到oddPrimesAndMultiples中的项。(当然,我可能完全误解了正在发生的事情,问题可能完全是另外一回事!)

如果我将updatedEntries更改为一个列表而不是IEnumerable,那么问题就不会出现。实际上,我现在已经在不使用LINQ的情况下重写了该语句,以便(可能?)更好地利用我使用的是SortedSet这一事实……但我仍然想知道为什么首先会出现这个问题

这是我的密码:

public static IEnumerable<int> QuickPrimes()
        {
            int firstPrime = 2;
            int firstOddPrime = 3;

            int currentValue = firstOddPrime;
            int currentMinimumMultiple;

            SortedSet<Tuple<int, int>> oddPrimesAndMultiples = new SortedSet<Tuple<int, int>>() { new Tuple<int, int> (firstOddPrime, firstOddPrime) };
            IEnumerable<Tuple<int, int>> updatedEntries;

            yield return firstPrime;
            yield return firstOddPrime;

            while (true)
            {
                currentMinimumMultiple = oddPrimesAndMultiples.First().Item1;
                while (currentValue < currentMinimumMultiple)
                {
                    yield return currentValue;
                    oddPrimesAndMultiples.Add(new Tuple<int, int> (currentValue * 3, currentValue));
                    currentValue += 2;
                }

                updatedEntries = oddPrimesAndMultiples.Where(tuple => tuple.Item1 == currentMinimumMultiple)
                                                        .Select(t => new Tuple<int, int>(t.Item1 + 2 * t.Item2, t.Item2));

                oddPrimesAndMultiples.RemoveWhere(t => t.Item1 == currentMinimumMultiple);
                oddPrimesAndMultiples.UnionWith(updatedEntries);
                currentValue += 2;
            }
        }

非常感谢

陷阱在于,
updateEntries
在一行中定义,但实际上在以后执行

要使其回到基础,请参见以下代码片段(来自Linqpad):

现在显示的是
6,7
,因为
updateEntries
被重新执行

ints.UnionWith(updatedEntries);
这将添加
6,7
,而您希望它添加第一个列表
6,7,8,9,10

ints.RemoveWhere(i => i > 7);
updatedEntries.Dump();

因此,在定义一个
IEnumerable
时,您应该始终知道它实际执行的时间。它始终作用于该特定点的程序状态。

使用yield关键字的IEnumerable可以提供非常不同的结果。明智地使用它。让我看看我是否理解这一点,您现在显示的代码正在工作,但以前不是因为您没有对updatedEntries分配进行“.ToList()”调用,对吗?您能提供问题的原因吗?在当前的帖子中,甚至不清楚代码是否存在您正在谈论的问题。@Fredy Treboux和Alexei-抱歉updatedEntries上的.ToList()不应该在那里-我在从更正的代码中粘贴代码时忘记删除它(我刚刚将updatedEntries的类型从列表更改回IEnumerable!)如果没有ToList()调用,则会发生InvalidOperation错误,因为正如我在上面所写的,这些项已从updatedEntries中删除,这意味着当我尝试首先调用它时,OddPrimeAndMultiples也是导致错误的条目!根据需要更新问题。请解释您观察到的情况的基本示例,我发现您的问题很难掌握。
ints.RemoveWhere(i => i > 7);
updatedEntries.Dump();
ints.UnionWith(updatedEntries);