Is there a LINQ extension or (a sensible/efficient set of LINQ entensions) that determine whether a collection has at least 'x' elements?

.net, c#, enumeration, linq, performance

Solution

public static bool AtLeast<T>(this IEnumerable<T> source, int count)
{
    // Optimization for ICollection<T>
    var genericCollection = source as ICollection<T>;
    if (genericCollection != null)
        return genericCollection.Count >= count;

    // Optimization for ICollection
    var collection = source as ICollection;
    if (collection != null)
        return collection.Count >= count;

    // General case
    using (var en = source.GetEnumerator())
    {
        int n = 0;
        while (n < count && en.MoveNext()) n++;
        return n == count;
    }
}

Problem

I have code that needs to know that a collection should not be empty or contain only one item. In general, I want an extension of the form: `bool collectionHasAtLeast2Items = collection.AtLeast(2);` I can write an extension easily, enumerating over the collection and incrementing an indexer until I hit the requested size, or run out of elements, but is there something already in the LINQ framework that would do this? My thoughts (in order of what came to me) are:: `bool collectionHasAtLeast2Items = collection.Take(2).Count() == 2;` or `bool collectionHasAtLeast2Items = collection.Take(2).ToList().Count == 2;` Which would seem to work, though the behaviour of taking more elements than the collection contains is not defined (in the documentation) Enumerable.Take Method , however, it seems to do what one would expect. It's not the most efficient solution, either enumerating once to take the elements, then enumerating again to count them, which is unnecessary, or enumerating once to take the elements, then constructing a list in order to get the count property which isn't enumerator-y, as I don't actually want the list. It's not pretty as I always have to make two assertions, first taking 'x', then checking that I actually received 'x', and it depends upon undocumented behaviour. Or perhaps I could use: `bool collectionHasAtLeast2Items = collection.ElementAtOrDefault(2) != null;` However, that's not semantically-clear. Maybe the best is to wrap that with a method-name that means what I want. I'm assuming that this will be efficient, I haven't reflected on the code. Some other thoughts are using `Last()`, but I explicitly don't want to enumerate through the whole collection. Or maybe `Skip(2).Any()`, again not semantically completely obvious, but better than `ElementAtOrDefault(2) != null`, though I would think they produce the same result? Any thoughts?

Original source