【发布时间】:2015-11-30 14:37:18
【问题描述】:
我有一个使用 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(...) 工作?
【问题讨论】:
-
如果您使用正确的 c# 版本(不确定哪个 atm),您可以使用
yield和yield return,这为我节省了很多精力,并且无需定义新的枚举器类bc 它为你完成了。 -
在您的情况下,多次访问
Current会产生不同的结果。不应该。 -
呃,有副作用的吸气剂!讨厌。