2015-01-02 15 views
7

Ku mojemu zaskoczeniu, pojawia się następujące stwierdzenie:Konwersja tablicy do IEnumerable <T>

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

narzekać nie jest w stanie przekonwertować z System.Array do System.Collection.Generic.IEnumerable. Myślałem, że ten ostatni odziedziczył tę pierwszą. Najwyraźniej się myliłem.

Ponieważ nie mogę LINQ to lub .ToList to, nie jestem pewien, jak sobie z tym poradzić prawidłowo. Wolałbym unikać jawnego rzucania i ponieważ jest to garść wartości dla enum, nie sądzę, że jako SomeType-będzie to również bardzo użyteczne.

+0

'Enum.GetValues' zwraca' Array' który nie jest silnie wpisany. Nic więc dziwnego. –

Odpowiedz

12

Ogólna klasa bazowa Array nie jest wpisana, więc nie implementuje żadnych interfejsów specyficznych dla danego typu; jednakże wektor wektor może być rzutowany bezpośrednio - a GetValues faktycznie zwraca wektor; tak:

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

czy może prościej:

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

Myślałem, że ten ostatni odziedziczył poprzedni.

Enum.GetValues powraca Array, który implementuje nierodzajową IEnumerable, więc trzeba dodać Obsada:

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

Działa to z LINQ ponieważ Cast<T> metodę rozszerzenia jest zdefiniowany dla non-generic IEnumerable interfejsu , nie tylko na IEnumerable<U>.

Edit: Rozmowa z ToList() unikaj nieefektywności związane z chodzeniem wielokrotnie się IEnumerable<T> wytwarzany metodami LINQ z realizacją odroczony. Dzięki, Marc, za świetny komentarz!

+0

To będzie boksować i rozpakowywać, gdy tylko zostanie udostępniony, uwaga. –

Powiązane problemy