Jak wyliczyć enum
w C #?
Np. Poniższy kod się nie kompiluje:
public enum Suit
{
Spades,
Hearts,
Clubs,
Diamonds
}
public void EnumerateAllSuitsDemoMethod()
{
foreach (Suit suit in Suit)
{
DoSomething(suit);
}
}
Daje to następujący błąd czasu kompilacji:
„Kolor” jest „typem”, ale jest używany jak „zmienna”
Nie działa na Suit
słowo kluczowe, drugie.
Odpowiedzi:
Uwaga : rzutowanie na
(Suit[])
nie jest absolutnie konieczne, ale przyspiesza kod o 0,5 ns .źródło
enum.GetValues
. W tym przypadku musisz użyć refleksji.enum E {A = 0, B = 0}
.Enum.GetValues
powoduje zwrócenie dwóch wartości, chociaż są one takie same.E.A == E.B
jest prawdą, więc nie ma różnicy. Jeśli chcesz mieć indywidualne nazwy, powinieneś poszukaćEnum.GetNames
.Distinct
rozszerzenia Linq (od .NET 3.5), więcforeach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }
.var
tego typu. Kompilator zmieni zmiennąObject
zamiast w wyliczenie. Podaj jawnie typ wyliczenia.Wydaje mi się, że naprawdę chcesz wydrukować nazwy każdego wyliczenia, a nie wartości. W takim przypadku
Enum.GetNames()
wydaje się to właściwe podejście.Nawiasem mówiąc, zwiększanie wartości nie jest dobrym sposobem na wyliczenie wartości wyliczenia. Powinieneś to zrobić zamiast tego.
Użyłbym
Enum.GetValues(typeof(Suit))
zamiast tego.źródło
Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray()
. W takim przypadku mogę iterować tablicę elementówSuits
wyliczeniowych, a nie ciągów.Suits suit in Enum.GetValues(typeof(Suits))
?Zrobiłem kilka rozszerzeń dla łatwego użycia enum. Może ktoś może go użyć ...
Sam enum musi być ozdobiony FlagsAttribute :
źródło
Niektóre wersje .NET Framework nie obsługują
Enum.GetValues
. Oto dobre obejście od Ideas 2.0: Enum.GetValues w Compact Framework :Podobnie jak w przypadku każdego kodu, który wymaga refleksji , powinieneś podjąć kroki, aby upewnić się, że działa tylko raz, a wyniki są buforowane.
źródło
return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>();
Użyj
Cast<T>
:Proszę bardzo
IEnumerable<Suit>
.źródło
from
klauzuli iforeach
deklaratorze nagłówka.Myślę, że jest to bardziej wydajne niż inne sugestie, ponieważ
GetValues()
nie jest wywoływane za każdym razem, gdy masz pętlę. Jest również bardziej zwięzły. I pojawia się błąd czasu kompilacji, a nie wyjątek czasu wykonywania, jeśliSuit
nie jestenum
.EnumLoop
ma tę całkowicie ogólną definicję:źródło
EnumLoop
z typem, który nie jest wyliczeniem, skompiluje się dobrze, ale wygeneruje wyjątek w czasie wykonywania.Nie dostaniesz się
Enum.GetValues()
w Silverlight .Oryginalny post na blogu autorstwa Einara Ingebrigtsena :
źródło
where T: Enum
Moje rozwiązanie działa w .NET Compact Framework (3.5) i obsługuje sprawdzanie typów w czasie kompilacji :
T valueType = new T()
, chętnie znajdę rozwiązanie.Połączenie wyglądałoby tak:
źródło
T valueType = default(T)
?new()
T
. Ponadtonew T()
wcale nie potrzebujesz , możesz wybrać tylko pola statyczne i zrobić to.GetValue(null)
. Zobacz odpowiedź Aubreya.where T: Enum
Myślę, że możesz użyć
źródło
źródło
Myślę, że buforowanie tablicy znacznie przyspieszy. Wygląda na to, że za każdym razem otrzymujesz nową tablicę (poprzez odbicie). Raczej:
To przynajmniej trochę szybciej, ja?
źródło
Trzy drogi:
Enum.GetValues(type)
// Od .NET 1.1, nie w Silverlight ani .NET Compact Frameworktype.GetEnumValues()
// Tylko w .NET 4 i nowszychtype.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null))
// Działa wszędzieNie jestem pewien, dlaczego
GetEnumValues
został wprowadzony w instancjach typu. Dla mnie to wcale nie jest bardzo czytelne.Posiadanie klasy pomocniczej
Enum<T>
jest dla mnie najbardziej czytelne i niezapomniane:Teraz dzwonisz:
Można również użyć pewnego rodzaju buforowania, jeśli wydajność ma znaczenie, ale nie spodziewam się, że będzie to w ogóle problem.
źródło
Po prostu łącząc najlepsze odpowiedzi, stworzyłem bardzo proste rozszerzenie:
Jest czysty, prosty i, według komentarza @ Jeppe-Stig-Nielsen, szybki.
źródło
where T: Enum
Istnieją dwa sposoby iteracji
Enum
:Pierwszy da ci wartości w formie na tablicy **
object
** s, a drugi da ci wartości w postaci tablicy **String
** s.Użyj go w
foreach
pętli, jak poniżej:źródło
Używam ToString (), a następnie dzielę i analizuję tablicę pluć w flagi.
źródło
Nie uważam, że to jest lepsze, a nawet dobre. Podaję tylko inne rozwiązanie.
Jeśli wartości wyliczeniowe mieszczą się w zakresie od 0 do n - 1, ogólną alternatywą jest:
Jeśli wartości wyliczenia są ciągłe i możesz podać pierwszy i ostatni element wyliczenia, to:
Ale to nie jest ściśle wyliczenie, tylko zapętlenie. Druga metoda jest jednak znacznie szybsza niż jakiekolwiek inne podejście ...
źródło
Jeśli potrzebujesz sprawdzania prędkości i typu w czasie kompilacji i wykonywania, ta metoda pomocnicza jest lepsza niż użycie LINQ do rzutowania każdego elementu:
I możesz użyć go jak poniżej:
Oczywiście możesz wrócić
IEnumerable<T>
, ale to nic tu nie kupi.źródło
where T: Enum
Oto działający przykład tworzenia wybranych opcji dla DDL :
źródło
(Akceptowana obecnie odpowiedź zawiera obsadę, która moim zdaniem nie jest potrzebna (chociaż mogę się mylić).)
źródło
To pytanie pojawia się w rozdziale 10 „ C # krok po kroku 2013 ”
Autor używa podwójnej pętli for do iteracji przez parę urządzeń wyliczających (aby utworzyć pełną talię kart):
W tym przypadku
Suit
iValue
oba są wyliczeniami:i
PlayingCard
jest obiektem karcianym o zdefiniowanymSuit
iValue
:źródło
Wiem, że to trochę bałagan, ale jeśli jesteś fanem jedno-liniowych, oto jeden:
źródło
Co jeśli wiesz, że typ będzie typu
enum
, ale nie wiesz, jaki dokładnie jest typ w czasie kompilacji?Metoda
getListOfEnum
wykorzystuje refleksję do pobrania dowolnego typu wyliczenia i zwracaIEnumerable
wszystkie wartości wyliczenia.Stosowanie:
źródło
Prosty i ogólny sposób przekonwertowania wyliczenia na coś, w co możesz wchodzić w interakcje:
I wtedy:
źródło
Dictionary
Nie jest dobrym pomysłem: jeśli maszEnum
jakenum E { A = 0, B = 0 }
wartość 0 dodano 2 razy generowaniaArgumentException
(nie można dodać takie sameKey
na ciąguDictionary
2 lub więcej razy!).Dictionary<,>
metodę o nazwieToList
? A dlaczego nie wrócićDictionary<T, string>
?Dodaj metodę
public static IEnumerable<T> GetValues<T>()
do swojej klasy, na przykład:Zadzwoń i przekaż swój enum. Teraz możesz iterować za pomocą
foreach
:źródło
enum
typy są nazywane „typami wyliczeń” nie dlatego, że są kontenerami, które „wyliczają” wartości (którymi nie są), ale ponieważ są zdefiniowane przez wyliczanie możliwych wartości dla zmiennej tego typu.(W rzeczywistości jest to nieco bardziej skomplikowane - typy wyliczeniowe są uważane za mające „leżącą u podstaw” liczbę całkowitą, co oznacza, że każda wartość wyliczenia odpowiada wartości całkowitej (jest to zwykle niejawne, ale może być określone ręcznie). C # został zaprojektowany w taki sposób, aby można było wypchać dowolne liczbę całkowitą tego typu do zmiennej wyliczeniowej, nawet jeśli nie jest to wartość nazwana).
Metoda System.Enum.GetNames może być używany do pobierania tablicę łańcuchów, które są nazwy wartości enum, jak sama nazwa wskazuje.
EDYCJA: Powinien zamiast tego zasugerować metodę System.Enum.GetValues . Ups
źródło
GetNames
metody powraca rzeczywiście tablica łańcuch, a PO wymaga wyliczający przez wartości.Próbowałem na wiele sposobów i uzyskałem wynik z tego kodu:
Aby uzyskać listę int z wyliczenia, użyj następujących. To działa!
źródło
Możesz także powiązać publiczne publiczne elementy wyliczeniowe bezpośrednio, używając odbicia:
źródło
Jeśli masz:
To:
Wyjdzie:
źródło
Ogólny sposób LINQ :
Stosowanie:
źródło