Что касается производительности ...
- Преобразование из списка в T [] включает в себя копирование всех данных из исходного списка во вновь выделенный массив.
- Преобразование из T [] в Список также включает в себя копирование всех данных из исходного списка во вновь распределенный Список.
- Преобразование из List или T [] в IEnumerable включает приведение, что составляет несколько циклов ЦП.
- Преобразование из IEnumerable в List включает в себя обновление, что также составляет несколько циклов ЦП.
- Преобразование из IEnumerable в T [] также включает апкастинг.
- Вы не можете привести IEnumerable к T [] или List, если только это не был T [] или List соответственно для начала. Вы можете использовать функции ToArray или ToList, но они также приведут к созданию копии.
- Доступ ко всем значениям в порядке от начала до конца в T [] в прямом цикле будет оптимизирован для использования простой арифметики указателей - что делает его самым быстрым из всех.
- Доступ ко всем значениям по порядку от начала до конца в Списке включает проверку каждой итерации, чтобы убедиться, что у вас нет доступа к значению за пределами массива, а затем фактический доступ к значению массива.
- Доступ ко всем значениям в IEnumerable включает создание объекта-перечислителя, вызов функции Next (), которая увеличивает указатель индекса, а затем вызов свойства Current, которое дает вам фактическое значение и помещает его в переменную, указанную вами в ваше заявление foreach. Как правило, это не так плохо, как кажется.
- Доступ к произвольному значению в IEnumerable предполагает запуск с начала и вызов Next () столько раз, сколько вам нужно, чтобы получить это значение. Как правило, это так плохо, как кажется.
В отношении идиом ...
Как правило, IEnumerable полезен для открытых свойств, параметров функций и часто для возвращаемых значений - и только если вы знаете, что собираетесь использовать значения последовательно.
Например, если бы у вас была функция PrintValues, если бы она была записана как PrintValues (List values), она могла бы работать только со значениями List, поэтому пользователю сначала пришлось бы преобразовать, если, например, они использовали T []. Аналогично, если функция была PrintValues (значения T []). Но если бы это были PrintValues (IEnumerable values), он мог бы иметь дело со списками, T [], стеками, хеш-таблицами, словарями, строками, наборами и т. Д. - любой коллекцией, реализующей IEnumerable, которая есть практически у каждого коллекция.
Что касается внутреннего использования ...
- Используйте список только в том случае, если вы не уверены, сколько предметов должно быть в нем.
- Используйте T [], если вы знаете, сколько элементов должно быть в нем, но вам нужен доступ к значениям в произвольном порядке.
- Придерживайтесь IEnumerable, если это то, что вам дали, и вам просто нужно использовать его последовательно. Многие функции будут возвращать IEnumerables. Если вам нужен доступ к значениям из IEnumerable в произвольном порядке, используйте ToArray ().
Также обратите внимание, что приведение отличается от использования ToArray () или ToList () - последнее включает в себя копирование значений, что действительно приводит к снижению производительности и памяти, если у вас много элементов. Первый просто сказать, что «собака - это животное, поэтому, как и любое животное, оно может есть» (удрученно) или «это животное - собака, поэтому оно может лаять» (повышенное настроение). Аналогично, все списки и T [] являются IEnumerables, но только некоторые IEnumerables являются списками или T [] s.