Wie können Sie ein enum
in C # aufzählen ?
ZB wird der folgende Code nicht kompiliert:
public enum Suit
{
Spades,
Hearts,
Clubs,
Diamonds
}
public void EnumerateAllSuitsDemoMethod()
{
foreach (Suit suit in Suit)
{
DoSomething(suit);
}
}
Und es gibt den folgenden Fehler beim Kompilieren:
'Anzug' ist ein 'Typ', wird aber wie eine 'Variable' verwendet.
Das Suit
Schlüsselwort, das zweite, schlägt fehl .
Antworten:
Hinweis : Die Umwandlung in
(Suit[])
ist nicht unbedingt erforderlich, beschleunigt jedoch den Code um 0,5 ns .quelle
enum.GetValues
. In diesem Fall müssen Sie Reflexion verwenden.enum E {A = 0, B = 0}
.Enum.GetValues
führt dazu, dass zwei Werte zurückgegeben werden, obwohl sie gleich sind.E.A == E.B
ist wahr, also gibt es keinen Unterschied. Wenn Sie individuelle Namen möchten, sollten Sie suchenEnum.GetNames
.Distinct
Erweiterung (seit .NET 3.5) verwendenforeach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }
.var
für den Typ zu verwenden. Der Compiler macht die Variable zu einerObject
anstelle der Aufzählung. Listen Sie den Aufzählungstyp explizit auf.Es sieht für mich so aus, als ob Sie wirklich die Namen jeder Aufzählung und nicht die Werte ausdrucken möchten. In diesem Fall
Enum.GetNames()
scheint der richtige Ansatz zu sein.Das Inkrementieren des Werts ist übrigens keine gute Möglichkeit, die Werte einer Aufzählung aufzulisten. Sie sollten dies stattdessen tun.
Ich würde
Enum.GetValues(typeof(Suit))
stattdessen verwenden.quelle
Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray()
. In diesem Fall kann ich ein Array vonSuits
Aufzählungselementen iterieren , keine Zeichenfolgen.Suits suit in Enum.GetValues(typeof(Suits))
?Ich habe einige Erweiterungen für die einfache Verwendung von Enum gemacht. Vielleicht kann es jemand benutzen ...
Die Aufzählung selbst muss mit dem FlagsAttribute verziert sein :
quelle
Einige Versionen des .NET Frameworks werden nicht unterstützt
Enum.GetValues
. Hier ist eine gute Problemumgehung von Ideas 2.0: Enum.GetValues in Compact Framework :Wie bei jedem Code, der Reflexion beinhaltet , sollten Sie Schritte unternehmen, um sicherzustellen, dass er nur einmal ausgeführt wird und die Ergebnisse zwischengespeichert werden.
quelle
return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>();
Verwendung
Cast<T>
:Los geht's
IEnumerable<Suit>
.quelle
from
Klausel und imforeach
Header-Deklarator.Ich denke, dies ist effizienter als andere Vorschläge, da
GetValues()
es nicht jedes Mal aufgerufen wird, wenn Sie eine Schleife haben. Es ist auch prägnanter. Und Sie erhalten einen Fehler zur Kompilierungszeit, keine Laufzeitausnahme, wenn diesSuit
keine istenum
.EnumLoop
hat diese völlig generische Definition:quelle
EnumLoop
einen Typ zu verwenden, der keine Aufzählung ist, wird er problemlos kompiliert, löst jedoch zur Laufzeit eine Ausnahme aus.Sie werden nicht
Enum.GetValues()
in Silverlight bekommen .Originaler Blogbeitrag von Einar Ingebrigtsen :
quelle
where T: Enum
Meine Lösung funktioniert in .NET Compact Framework (3.5) und unterstützt die Typprüfung beim Kompilieren :
T valueType = new T()
, würde ich mich über eine Lösung freuen.Ein Anruf würde so aussehen:
quelle
T valueType = default(T)
?new()
T
. Außerdem brauchen Sienew T()
überhaupt nicht, Sie können nur die statischen Felder allein auswählen und tun.GetValue(null)
. Siehe Aubreys Antwort.where T: Enum
Ich denke du kannst es benutzen
quelle
quelle
Ich denke, das Zwischenspeichern des Arrays würde es erheblich beschleunigen. Es sieht so aus, als würden Sie jedes Mal ein neues Array (durch Reflexion) erhalten. Lieber:
Das ist zumindest etwas schneller, ja?
quelle
Drei Wege:
Enum.GetValues(type)
// Seit .NET 1.1 nicht in Silverlight oder .NET Compact Frameworktype.GetEnumValues()
// Nur unter .NET 4 und höhertype.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null))
// Funktioniert überallIch bin nicht sicher, warum
GetEnumValues
auf Typinstanzen eingeführt wurde. Es ist für mich überhaupt nicht sehr lesbar.Eine Helferklasse wie diese zu haben,
Enum<T>
ist für mich am lesbarsten und unvergesslichsten:Jetzt rufst du an:
Man kann auch eine Art Caching verwenden, wenn es auf die Leistung ankommt, aber ich erwarte nicht, dass dies überhaupt ein Problem ist.
quelle
Nur durch die Kombination der Top-Antworten habe ich eine sehr einfache Erweiterung zusammengestellt:
Es ist sauber, einfach und laut @ Jeppe-Stig-Nielsens Kommentar schnell.
quelle
where T: Enum
Es gibt zwei Möglichkeiten, ein zu iterieren
Enum
:Der erste gibt Ihnen Werte in Form auf einem Array von **
object
** s und der zweite gibt Ihnen Werte in Form eines Arrays von **String
** s.Verwenden Sie es in einer
foreach
Schleife wie folgt:quelle
Ich benutze ToString () und teile und analysiere das Spit-Array in Flags.
quelle
Ich bin nicht der Meinung, dass dies besser oder sogar gut ist. Ich sage nur noch eine andere Lösung.
Wenn die Enum-Werte streng zwischen 0 und n - 1 liegen, ist eine generische Alternative:
Wenn Aufzählungswerte zusammenhängend sind und Sie das erste und letzte Element der Aufzählung angeben können, dann:
Aber das ist keine strikte Aufzählung, sondern nur eine Schleife. Die zweite Methode ist jedoch viel schneller als jeder andere Ansatz ...
quelle
Wenn Sie zur Erstellung und Laufzeit eine Geschwindigkeits- und Typprüfung benötigen, ist diese Hilfsmethode besser als die Verwendung von LINQ zum Umwandeln jedes Elements:
Und Sie können es wie folgt verwenden:
Natürlich können Sie zurückkehren
IEnumerable<T>
, aber das bringt Ihnen hier nichts.quelle
where T: Enum
Hier ist ein Arbeitsbeispiel zum Erstellen von Auswahloptionen für eine DDL :
quelle
(Die aktuell akzeptierte Antwort hat eine Besetzung, die ich nicht für nötig halte (obwohl ich mich möglicherweise irre).)
quelle
Diese Frage erscheint in Kapitel 10 von " C # Step by Step 2013 ".
Der Autor verwendet eine doppelte for-Schleife, um zwei Enumeratoren zu durchlaufen (um ein vollständiges Kartenspiel zu erstellen):
In diesem Fall
Suit
undValue
sind beide Aufzählungen:und
PlayingCard
ist ein Kartenobjekt mit einem definiertenSuit
undValue
:quelle
Ich weiß, dass es ein bisschen chaotisch ist, aber wenn Sie ein Fan von Einzeiler sind, hier ist einer:
quelle
Was ist, wenn Sie wissen, dass der Typ ein
enum
Typ ist, Sie aber nicht wissen, wie der genaue Typ zur Kompilierungszeit lautet?Die Methode
getListOfEnum
verwendet Reflektion, um einen beliebigen Aufzählungstyp zu verwenden, und gibt einenIEnumerable
aller Aufzählungswerte zurück.Verwendungszweck:
quelle
Eine einfache und allgemeine Möglichkeit, eine Aufzählung in etwas umzuwandeln, mit dem Sie interagieren können:
Und dann:
quelle
Dictionary
ist keine gute Idee: Wenn Sie eine haben ,Enum
wieenum E { A = 0, B = 0 }
der Wert 0 2 mal hinzugefügt erzeugt einArgumentException
(Sie denselben nicht hinzufügen können ,Key
auf einemDictionary
2 oder mehrmals!).Dictionary<,>
von einer Methode namens zurückgebenToList
? Auch warum nicht zurückkehrenDictionary<T, string>
?Fügen Sie
public static IEnumerable<T> GetValues<T>()
Ihrer Klasse eine Methode hinzu , wie:Rufen Sie an und geben Sie Ihre Aufzählung weiter. Jetzt können Sie es durchlaufen mit
foreach
:quelle
enum
Typen werden als "Aufzählungstypen" bezeichnet, nicht weil sie Container sind, die Werte "auflisten" (was sie nicht sind), sondern weil sie durch Auflisten der möglichen Werte für eine Variable dieses Typs definiert werden.(Tatsächlich ist das etwas komplizierter - Aufzählungstypen haben einen "zugrunde liegenden" Ganzzahltyp, was bedeutet, dass jeder Aufzählungswert einem Ganzzahlwert entspricht (dies ist normalerweise implizit, kann aber manuell angegeben werden). C # wurde entworfen auf eine Weise, dass Sie eine beliebige Ganzzahl dieses Typs in die Enum-Variable einfügen können, auch wenn es sich nicht um einen "benannten" Wert handelt.)
Die System.Enum.GetNames-Methode kann verwendet werden, um ein Array von Zeichenfolgen abzurufen, die die Namen der Enum-Werte sind, wie der Name schon sagt.
BEARBEITEN: Hätte stattdessen die System.Enum.GetValues- Methode vorschlagen sollen . Hoppla.
quelle
GetNames
Methode gibt zwar ein String-Array zurück, aber das OP benötigt einen Enumerator für die Werte.Ich habe viele Möglichkeiten ausprobiert und das Ergebnis aus diesem Code erhalten:
Verwenden Sie Folgendes, um eine Liste von int aus einer Aufzählung abzurufen. Es klappt!
quelle
Sie können sich auch direkt an die öffentlichen statischen Mitglieder der Aufzählung binden, indem Sie Reflection verwenden:
quelle
Wenn Sie haben:
Diese:
Wird ausgegeben:
quelle
LINQ Generic Way:
Verwendungszweck:
quelle