2015-01-02 2 views
7

К моему удивлению, я получаю следующее заявление:Преобразование массива в IEnumerable <T>

public static IEnumerable<SomeType> AllEnums 
    => Enum.GetValues(typeof(SomeType)); 

жаловаться не в состоянии конвертировать из System.Array в System.Collection.Generic.IEnumerable. Я думал, что последний унаследовал от первого. Видимо, я ошибся.

Поскольку я не могу LINQ это или .ToList это, я не уверен, как с этим бороться. Я бы предпочел избегать явного литья, и, поскольку это куча значений для enum, я не думаю, что как SomeType -ing это будет очень полезно.

+0

'Enum.GetValues' возвращает' Array', который не сильно типизированных. Так что не удивляйтесь. –

ответ

12

Общий базовый класс Array не напечатан, поэтому он не реализует никаких типов конкретных интерфейсов; однако, вектор может быть отлит напрямую - и GetValues фактически возвращает вектор; так:

public static IEnumerable<SomeType> AllEnums 
    = (SomeType[])Enum.GetValues(typeof(SomeType)); 

или, возможно, проще:

public static SomeType[] AllEnums 
    = (SomeType[])Enum.GetValues(typeof(SomeType)); 
4

Я думал, что последний наследуется от прежнего.

Enum.GetValues возвращает Array, который реализует необщего IEnumerable, поэтому вам нужно добавить ролях:

public static IEnumerable<SomeType> AllEnums = Enum.GetValues(typeof(SomeType)) 
    .Cast<SomeType>() 
    .ToList(); 

Это работает с LINQ, поскольку Cast<T> метод расширения определяется для необщего IEnumerable интерфейса , а не только на IEnumerable<U>.

Edit: Вызов ToList() избегайте неэффективности, связанный с ходьбой несколько раз в IEnumerable<T> производится с помощью методов LINQ с отсрочкой исполнения. Спасибо, Марк, за отличный комментарий!

+0

Это будет бокс и распаковка при каждом доступе, обратите внимание. –