Ho una semplice implementazione di sequenza di Fibonacci utilizzando BigInteger:IEnumerable <T> Salta sulla sequenza illimitata
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();}
}
Si tratta di una sequenza di illimitata come MoveNext()
restituisce sempre vero.
Quando viene chiamato utilizzando
var fs = new FibonacciSequence();
fs.Take(10).ToList().ForEach(_ => Console.WriteLine(_));
l'uscita è come previsto (1,1,2,3,5,8, ...)
voglio selezionare 10 articoli, ma a partire da 100 posizione. Ho provato a chiamare tramite
fs.Skip(100).Take(10).ToList().ForEach(_ => Console.WriteLine(_));
ma questo non funziona, come uscite dieci elementi dall'inizio (cioè l'uscita è nuovamente 1,1,2,3,5,8, ...).
I posso saltare chiamando SkipWhile
fs.SkipWhile((b,index) => index < 100).Take(10).ToList().ForEach(_ => Console.WriteLine(_));
che emette correttamente 10 elementi a partire dall'elemento 100 °.
C'è qualcos'altro che deve/può essere implementato nell'enumeratore per rendere operativo il Skip(...)
?
Se siete nella versione corretta di C# (non sono sicuro quale atm) potete usare 'yield' e' yield return' che mi hanno risparmiato un sacco di sforzi, ed elimina la definizione di una nuova classe di enumerazione bc fatta per tu. –
nel tuo caso, l'accesso a 'Current' diverse volte produce risultati diversi. Non dovrebbe. – njzk2
Uhhh, un getter con effetti collaterali! Cattiva. – usr