IEnumerable’s are finicky things, you have to tickle them just right to get the most out of them.
A typical problem is that you sometimes need to partition them (ie: cut them in pieces -partitions- of equal size) so that yo can pass them to parallel tasks or write them to separate files, or whatever else you can think of.
I’ve seen many different implementations of a partitioner, but most of them miss the point of using an
IEnumerable in the first place: an
IEnumerable is a sequence of items that are presented to us one item at a time. We have no way of knowing how many items there are, and we do not know if these items have already been initialized or even if any memory has been allocated for them. We should not presume how the
IEnumerable may be used. If it contains an array, we can do whatever we want to it. But what if it contains a SQL backed LINQ query, or some other construct that depends on delayed execution? How many times can we actually go through the
A naive implementation of partitioning would call the LINQ extension
.Count() on the
IEnumerable, and then divide the returned value by the count of partitions we want to achieve. But that would be wrong, because we don’t even know if whatever lies behind the
IEnumerable will even work again once we’ve called
An even naiver implementation would just call
.ToArray() to get all the items and be done with it. But that’s a luxury we can’t always afford. Maybe we don’t have enough memory for all the items in the array, or maybe we don’t have the time to first instantiate all of them.
So, here’s a partitioner that does not violate the intent of the contract that is the