Если метод берет параметр системы типов. Наборы. IList может я законно/безопасно передавать значение типа System.Collections.Generic.IEnumerable<T>
?
Я ценил бы полное объяснение того, почему это возможно и что на самом деле происходит с объектом T
когда IEnumerable<T>
используется в методе.
Это преобразовывается в базовый тип Объекта?
Это используется в качестве System.Collections.IEnumerable
?
Есть ли какие-либо сценарии, где это вызовет проблемы (т.е. проблемы производительности)?
Заранее спасибо, John
Нет, Вы не можете передать IEnumerable
методу, который принимает IList
. Интерфейс IEnumerable
не конвертируется в IList
и попытка передать переменную типа IEnumerable
методу, принимающему IList
, приведет к ошибке компиляции.
Для того, чтобы сделать эту работу, вам нужно будет сделать одну из следующих
IEnumerable
, поддерживать ссылку на тип, который реализует как IEnumerable
, так и IList
. List
является хорошим кандидатом здесьIEnumerable
в новый объект, который конвертируется в IList
. Например, в версии 3.5+ можно вызвать метод расширения .ToList()
для создания нового List
над перечислением. Вы должны будете вызвать ToList()
.
http://msdn.microsoft.com/en-us/library/bb342261.aspx
Нет. Нельзя без использования метода расширения ToList()
. Я думаю, что это не должно приводить к тому, что возникнет большая проблема с производительностью - если у вас есть альтернатива, разместите их и сравните.
Вы также можете использовать новый List
- в документации сказано, что эта функция является операцией O(n)
, но я больше ничего не могу найти о ToList()
. Также помните, что List
также реализует IList
и IList
.
IEnumerable не разрешает индексированный доступ к коллекции, в то время как IList разрешает. Таким образом, IList больше чем IEnumerable, и вам это с рук не сойдет. Конечно, некоторые классы реализуют оба интерфейса (например, List<>), и они будут отлично работать.
Если вам нужно перейти из IEnumerable в IList, вы можете попробовать сначала кастинг, если повезет, он будет работать. Если нет, вам придется пролистать коллекцию IEnumerable и собрать новый IList.
Edit: используйте ToList() вместо того, чтобы пролистать себя, как предлагали другие.
.Нет, ты не можешь пропустить IEnumerable. IList реализует IEnumerable, поэтому, если вы передаете свой метод IList, вы можете безопасно использовать его как IEnumerable. VS не скомпилирует следующее:
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>'