Sono occasionalmente nella situazione che devo elaborare un numero enumerabile più volte. Se l'enumerazione è costosa, non ripetibile e genera molti dati (come un IQueryable che legge da un database), l'enumerazione di più volte non è un'opzione, né la memorizzazione dei risultati avviene in memoria.
Fino a oggi ho finito spesso a scrivere classi di aggregatori in cui potevo inserire elementi in un ciclo foreach e alla fine leggere i risultati - molto meno elegante di LINQ.
Ma aspetta, ho appena detto "push"? Non suona come ... reattivo? Quindi stavo pensando durante la passeggiata di stanotte. A casa ho provato - e funziona!
Il frammento di esempio mostra come ottenere sia il numero massimo di voci minimo e da una sequenza di numeri interi in un singolo passaggio, utilizzando gli operatori LINQ normali (quelli di Rx, cioè):
public static MinMax GetMinMax(IEnumerable<int> source)
{
// convert source to an observable that does not enumerate (yet) when subscribed to
var connectable = source.ToObservable(Scheduler.Immediate).Publish();
// set up multiple consumers
var minimum = connectable.Min();
var maximum = connectable.Max();
// combine into final result
var final = minimum.CombineLatest(maximum, (min, max) => new MinMax { Min = min, Max = max });
// make final subscribe to consumers, which in turn subscribe to the connectable observable
var resultAsync = final.GetAwaiter();
// now that everybody is listening, enumerate!
connectable.Connect();
// result available now
return resultAsync.GetResult();
}
Questo non è un rispondere alla domanda, che è stata "È corretto chiamare i metodi Linq su IEnumerable più di una volta?" ... la risposta è no". –
Bene, quello che "OK" significa è un po 'poco chiaro. Puoi scorrere su una lista tutte le volte che vuoi. Cito le ramificazioni di questo nella mia risposta. Come non va bene iterare su di loro? Pubblica la tua risposta se la pensi così (anche se c'è già una risposta accettata). –
È perfettamente chiaro. 'items' è un oggetto IEnumerable, non un elenco e puoi attraversarlo solo una volta. Non è necessario pubblicare un'altra risposta, ma è importante che i lettori capiscano che questo è sbagliato e non tocca nemmeno la domanda. –