我有一个使用BigInteger的斐波那契数列的简单实现:

internal class FibonacciEnumerator : IEnumerator<BigInteger>
    {
        private BigInteger _previous = 1;
        private BigInteger _current = 0;

        public void Dispose(){}

        public bool MoveNext() {return true;}

        public void Reset()
        {
            _previous = 1;
            _current = 0;
        }

        public BigInteger Current
        {
            get
            {
                var temp = _current;
                _current += _previous;
                _previous = temp;
                return _current;
            }
        }

        object IEnumerator.Current { get { return Current; }
        }
    }

    internal class FibonacciSequence : IEnumerable<BigInteger>
    {
        private readonly FibonacciEnumerator _f = new FibonacciEnumerator();

        public IEnumerator<BigInteger> GetEnumerator(){return _f;}

        IEnumerator IEnumerable.GetEnumerator(){return GetEnumerator();}
    }

这是一个无限制的序列,因为MoveNext()始终返回true。

当使用
var fs = new FibonacciSequence();
fs.Take(10).ToList().ForEach(_ => Console.WriteLine(_));

输出与预期的一样(1,1,2,3,5,8,...)

我想选择10个项目,但要从第100个位置开始。我尝试通过致电
fs.Skip(100).Take(10).ToList().ForEach(_ => Console.WriteLine(_));

但这不起作用,因为它从头开始输出十个元素(即,输出再次为1,1,2,3,5,8,...)。

我可以通过调用SkipWhile跳过它
fs.SkipWhile((b,index) => index < 100).Take(10).ToList().ForEach(_ => Console.WriteLine(_));

从第100个元素开始正确输出10个元素。

要使Skip(...)工作,枚举器中是否还需要/可以实现其他功能?

最佳答案

Skip(n)不访问Current,它仅调用MoveNext() n次。

因此,您需要在MoveNext()中执行增量,即the logical place for that operation anyway:

关于c# - IEnumerable <T>无限顺序跳过,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32398006/

10-11 08:17