Материализация последовательности в C#
Ленивый IEnumerable вычисляет элементы при переборе. ToList и ToArray проходят последовательность один раз и сохраняют копию в памяти - после этого можно многократно обращаться по индексу или перечислять без повторного выполнения генератора.
Материализация нужна, когда один и тот же набор понадобится несколько раз или когда нужен доступ по номеру. У очень длинной или бесконечной последовательности такая копия может быть дорогой.
Range(1, 3) берёт три числа, начиная с 1: получаются 1, 2 и 3. Второй аргумент - это количество, а не последний номер. Сохраним их в список и прочитаем последнее. Индексы начинаются с нуля, поэтому позиция 2 - это число 3. Повторный проход по buf уже не вызывает Range:
using System.Collections.Generic;
using System.Linq;
IEnumerable<int> src = Enumerable.Range(1, 3);
List<int> buf = src.ToList();
Console.WriteLine(buf[2]); // выведет 3
Последовательность отдаёт названия "oak" и "elm" по одному. Сохраните их в список и выведите второе название.