Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IEnumerable在无限序列上跳过_C#_Linq_Fibonacci_Skip - Fatal编程技术网

C# IEnumerable在无限序列上跳过

C# IEnumerable在无限序列上跳过,c#,linq,fibonacci,skip,C#,Linq,Fibonacci,Skip,我有一个使用BigInteger的Fibonacci序列的简单实现: internal class FibonacciEnumerator : IEnumerator<BigInteger> { private BigInteger _previous = 1; private BigInteger _current = 0; public void Dispose(){} public bool MoveN

我有一个使用BigInteger的Fibonacci序列的简单实现:

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();}
    }
输出如预期的1,1,2,3,5,8

我想选择10项,但从第100位开始。我试着打电话给他

fs.Skip(100).Take(10).ToList().ForEach(_ => Console.WriteLine(_));
但这不起作用,因为它从一开始就输出十个元素,即输出再次为1,1,2,3,5,8

我可以打电话跳过它

fs.SkipWhile((b,index) => index < 100).Take(10).ToList().ForEach(_ => Console.WriteLine(_));
从第100个元素开始正确输出10个元素

在枚举器中是否还有其他需要/可以实现的内容,以使跳过。。。工作?

Skipn不访问当前,它只调用MoveNext n次

因此需要在MoveNext中执行增量,即:

Current不会移动枚举数的位置,对Current的连续调用将返回相同的对象,直到调用MoveNext或Reset

将逻辑移到MoveNext:


Skip10只是调用MoveNext 10次,然后调用Current。在MoveNext中执行操作比在current中执行操作更有逻辑意义。

CodeCaster的答案很准确-我只想指出,对于这样的事情,您实际上不需要实现自己的枚举:

public IEnumerable<BigInteger> FibonacciSequence()
{
  var previous = BigInteger.One;
  var current = BigInteger.Zero;

  while (true)
  {
    yield return current;

    var temp = current;
    current += previous;
    previous = temp;
  }
}

编译器将为您创建枚举数和可枚举数。对于这样一个简单的可枚举函数,差别并不是很大,你只需要避免大量的样板文件,但是如果你真的需要比简单递归函数更复杂的东西,它会产生巨大的差别。

。收益率返回是您的朋友。如果您使用的是正确的c版本,则不确定您可以使用哪个atm收益率和收益率返回,这为我节省了很多精力,并且消除了定义新的枚举器类bc的麻烦。在您的情况下,多次访问Current会产生不同的结果。不应该。嗯,有副作用的吸气剂!肮脏的
public bool MoveNext() 
{
    var temp = _current;
     _current += _previous;
     _previous = temp;
    return true;
}

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

public BigInteger Current
{
    get
    {
        return _current;
    }
}
public IEnumerable<BigInteger> FibonacciSequence()
{
  var previous = BigInteger.One;
  var current = BigInteger.Zero;

  while (true)
  {
    yield return current;

    var temp = current;
    current += previous;
    previous = temp;
  }
}