2010-01-04 5 views
8

Если метод принимает параметр типа System.Collections.IList, могу ли я законно/безопасно передать значение типа System.Collections.Generic.IEnumerable<T>?Преобразование IEnumerable <T> в IList

Я хотел бы получить подробное объяснение, почему это возможно и что на самом деле происходит с объектом T, когда в методе используется IEnumerable<T>.

Он преобразуется в базовый тип объекта?

Используется ли он как System.Collections.IEnumerable?

Существуют ли сценарии, в которых это может вызвать проблемы (например, проблемы с производительностью)?

Спасибо заранее, Джон

ответ

25

Нет, Вы не можете передать IEnumerable<T> к способу, который принимает IList. Интерфейс IEnumerable<T> не конвертируется в IList и пытается передать переменную типа IEnumerable<T> методу, принимающему IList, приведет к ошибке компиляции.

Для того, чтобы сделать эту работу, Вы должны будете сделать одно из следующих действий

  1. Вместо того, чтобы в IEnumerable<T>, сохранить ссылку на тип, который реализует как IEnumerable<T> и IList. List<T> является хорошим кандидатом здесь
  2. Преобразование IEnumerable<T> экземпляр в новый объект, который можно конвертировать в IList. Например, в 3.5+ вы можете вызвать метод расширения .ToList() для создания нового List<T> по перечислению.
2

No. Вы не можете, не используя метод ToList() расширения. Я думаю, что это не должно вызывать , что большой проблемы с производительностью - если у вас есть альтернатива, время и сравнение.

Вы также можете использовать new List<T>(myIEnumerable) - в документации говорится, что эта функция является операцией O(n), но я ничего не могу найти о ToList(). Также помните, что List<T> также реализует IList, а также IList<T>.

1

IEnumerable не позволяет индексировать доступ к коллекции, тогда как IList делает. Таким образом, IList больше, чем IEnumerable, и вы не сможете избежать этого. Конечно, некоторые классы реализуют оба интерфейса (например, список <>), и они будут работать нормально.

Если вам нужно перейти от IEnumerable к IList, вы можете попробовать бросить первым, если вам повезет, это сработает. Если нет, вам нужно будет просмотреть коллекцию IEnumerable и создать новый IList.

Редактировать: используйте ToList() вместо того, чтобы указывать себя, как предложили другие.

0

Нет, вы не можете передать ему IEnumerable. IList реализует IEnumerable, поэтому, если вы передадите свой метод IList, вы можете безопасно использовать его как IEnumerable. ВС не будет компилировать следующее: вернулся

private static void Test(IList<int> list){ } 

Test(Enumerable.Range(0, 10)); 

Ошибка:

Argument '1': cannot convert from System.Collections.Generic.IEnumerable<int>' to 'System.Collections.Generic.IList<int>' 

 Смежные вопросы

  • Нет связанных вопросов^_^