Optimize LINQ for IList
I agree with Rafe that the undefined behavior is more correct. Only versioned collections can throw exceptions and not all collections are versioned (arrays being the largest example). Even versioned collections might misbehave if you make exactly 2^32 changes between calls to MoveNext
.
Assuming you really care about the versioning behavior, the solution is to get an Enumerator
for the IList
and call MoveNext
on it for every iteration:
public static IEnumerable<T> Skip<T>(this IList<T> source, int count)
{
using (var e = source.GetEnumerator())
while (count < source.Count && e.MoveNext())
yield return source[count++];
}
This way you get O(1) behavior by indexing, but you still get all the exception throwing behavior of calling MoveNext
. Note that we only call MoveNext
for the exception side-effects; we ignore the values that it's enumerating over.