Search code examples
c#.netlistcollectionslinq-to-objects

Does List<T>.Last() enumerate the collection?


Considering the boundaries of a List are known, does .Last() enumerate the collection?

I ask this because the documentation says that it is defined by Enumerable (in which case it would need to enumerate the collection)

If it does enumerate the collection then I can simply access the last element by index (as we know the .Count of a List<T>) but it seems silly to have to do this....


Solution

  • No, it does not enumerate it. It first checks if the enumerable can be casted to an IList<T>(which Array and List<T> implement), then the index will be used directly without enumeration.

    Enumerable.Last source:

    public static TSource Last<TSource>(this IEnumerable<TSource> source) {
        if (source == null) throw Error.ArgumentNull("source");
        IList<TSource> list = source as IList<TSource>;
        if (list != null) {
            int count = list.Count;
            if (count > 0) return list[count - 1];
        }
        else {
            using (IEnumerator<TSource> e = source.GetEnumerator()) {
                if (e.MoveNext()) {
                    TSource result;
                    do {
                        result = e.Current;
                    } while (e.MoveNext());
                    return result;
                }
            }
        }
        throw Error.NoElements();
    }
    

    Side-note: only single dimensional arrays implement IList<T>, which makes sense.