Enumerable.Last <T>() и С#

Скажем, у меня есть простой массив:

double[] myDoubleArray = new double[] { 0, 1, 2, 3, 4, 5 };

Это как исполнитель:

double last = myDoubleArray.Last();

как это?

double last = myDoubleArray[myDoubleArray.Length - 1];

Будет ли Last() перечислить весь массив, даже если он может сделать вышеуказанную оптимизацию?

Если бы я передал некоторый другой IEnumerable (скажем, тот, который был получен), Last() должен был бы перечислить последовательность. Я предпочитаю использовать Last(), потому что код выглядит более чистым, но я бы не стал жертвовать, если он перечисляет последовательность.

Ответ 1

Нет, он не будет перебирать все элементы. Вот код Enumerable.Last() из рефлектора. Как вы видите, он делает такую ​​оптимизацию

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> enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                TSource current;
                do
                {
                    current = enumerator.Current;
                }
                while (enumerator.MoveNext());
                return current;
            }
        }
    }
    throw Error.NoElements();
}

Ответ 2

Нет, Last без предиката оптимизируется для случая IList<T>, включая одномерные массивы.

С помощью предиката он не выполняет оптимизацию. В частности, он не работает в обратном направлении от конца (что может изменить результаты из-за исключений).

По-прежнему будет немного быстрее обращаться к последнему элементу напрямую, но Last() будет более читаемым и будет только "постоянным временем" другим - он не изменит операцию O (1) на O (N) в этом случае.

Подробнее о Last см. в блоге Edulinq об этом.

Обратите внимание, что оптимизация не документирована, поэтому, возможно, вы не должны полагаться на нее. На практике я не могу себе представить, чтобы он менялся, чтобы стать O (N):)