Reputation: 2020
The following code when compiled is lowered into over 100 lines of code in a state machine, just to enumerate the inner IEnumerable, which would have its own state machine.
This feels inefficient.
public abstract class C {
public abstract (IEnumerable<int>,bool) getABatch();
IEnumerable<int> getLots(){
bool hasMore;
do{
(var stuff,hasMore)=getABatch();
foreach(var thing in stuff)
yield return thing;
} while (hasMore)
}
}
I want to get lots of batches and return them all as 1 long enumerable. I'd prefer to not build i long list, as i don't know how much data will come through (could be millions of items).
Question: Is there a better way to handle this enumerable than manually yielding them all the inner elements? It feels like there should be an easier way to do this, given the inner enumerable has all the info it needs.
Upvotes: 1
Views: 354
Reputation: 386
Is there a reason you need to specifically enumerate over the getABatch collection? If not, you could just return getABatch();
. If yes, but nothing else needs to happen in the loop, you could also use the ToArray()
extension, which will iterate over the collection for you and then you can return the array, which is still an IEnumerable.
EDIT: I see you've edited the question to fetch batches in a while loop. In this case I would say there's actually nothing wrong with using a yield return. However, you could initialize a result collection and simply add everything to it before finishing.
IEnumerable<int> getLots(){
bool hasMore;
var result = new List<int>();
do{
(var stuff,hasMore)=getABatch();
result.AddRange(stuff);
} while (hasMore)
return result;
}
Upvotes: 4