Кажется, что не всем понятна борьба за использование исходной коллекции в .NET. Поясняю весьма избитую истину - бежать по
IEnumerable (IList, IReadOnlyCollection и т.п.) сильно дороже, чем по исходной коллекции. Как по памяти, так и по скорости. Позволю себе напомнить внутреннюю работу .NET на примере List<T>.
Класс
List<T> обладает методом GetEnumerator, который вызывается при попытке сделать по нему foreach. Как можно заметить, List<T>.Enumerator - структура. Это важно, поскольку структура создаётся на стеке, а её методы вызываются напрямую (см. call и callvirt). Это позволяет пробегать по списку быстро и без затрат на выделение места в куче, а значит без работы GC.Но стоит нам скастить List<T> к IList<T> - ситуация изменится. В этом случае foreach вызовет метод интерфейса
IEnumerable.GetEnumerator, который возвращает IEnumerator<T>, то есть интерфейс перечислителя. В случае List’a это будет та же самая структура, но размещённая в куче и доступом к её методам через callvirt. То есть мы не только создадим небольшой memory traffic, но и сильно замедлим перебор коллекции.Насколько всё это будет медленнее - см. результаты бенчмарка.
