Iterowanie po wartościach enuma w .NET.
Hej,
tytuł tego newsa może brzmieć nieco dziwacznie, jednak ostatnio potrzebna mi była dokładnie taka metoda, pozwalająca przejrzeć w pętli wszystkie możliwe wartości dostępne w pewnym wyliczeniu. Dla ustalenia uwagi niech będzie to wyliczenie CodeLanguages.
<i> enum CodeLanguage { CSharp, VBNet, FSharp } </i>
Pierwsze rozwiązanie, które znalazłem było dość proste i polegało na wykorzystaniu statycznej metody GetValues udostępnianej przez klasę Enum.
<i> foreach (CodeLanguage cLang in Enum.GetValues(typeof(CodeLanguage))) { ... } </i>
Z taką funkcją można już łatwo stworzyć typowaną metodę, która pozwoli zwrócić kolekcję wartości dla dowolnego enuma.
<i> public static IEnumerable<T> GetEnumValues<T>() { if (!typeof(T).IsSubclassOf(typeof(Enum))) { throw new Exception("Podany typ to nie enumeracja."); } return (T[])Enum.GetValues(typeof(T)); } </i>
Jednak jeśli programujemy w CompactFramework lub piszemy w Silverlight szybko zauważymy, że klasa Enum metody GetValues zwyczajnie nie posiada :P. Można jednak wykorzystać mechanizm refleksji, aby wydobyć informacje o interesujących nas polach :).
Nasz kod będzie miał wówczas postać:
<i> public static IEnumerable<T> GetEnumValues<T>() where T: new() { T enumObject = new T(); List<T> values = new List<T>(); foreach (FieldInfo field in typeof(T).GetFields(BindingFlags.Static | BindingFlags.Public)) { values.Add((T)field.GetValue(enumObject)); } return values; } </i>
Oczywiście można użyć też LINQ do skrócenia zapisu, jednak nie chciałem zaciemniać sposobu działania tej metody.
Mam nadzieję, że ten krótki artykuł pomoże osobom szukającym informacji o tym jak wyliczyć wartości wyliczenia :).
Jeśli będziecie mieli dodatkowe pytania związane z tematem, piszcie.
Pozdrawiam,
Łukasz