769 Stimmen

Wie konvertiere ich eine Aufzählung in eine Liste in C#?

Gibt es eine Möglichkeit zur Konvertierung eines enum zu einer Liste, die alle Optionen der Aufzählung enthält?

1335voto

Jake Pearson Punkte 25753

Dies führt zu einer IEnumerable<SomeEnum> aller Werte einer Enum.

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();

Wenn Sie wollen, dass das ein List<SomeEnum> fügen Sie einfach hinzu .ToList() nach .Cast<SomeEnum>() .

Um die Cast-Funktion auf ein Array anzuwenden, müssen Sie die System.Linq in Ihrem Verwendungsbereich.

137voto

Gili Punkte 1277

Das ist viel einfacher:

Enum.GetValues(typeof(SomeEnum))
    .Cast<SomeEnum>()
    .Select(v => v.ToString())
    .ToList();

122voto

Jeppe Stig Nielsen Punkte 57056

Die kurze Antwort lautet: nutzen:

(SomeEnum[])Enum.GetValues(typeof(SomeEnum))

Wenn Sie das für eine lokale Variable brauchen, ist es var allSomeEnumValues = (SomeEnum[])Enum.GetValues(typeof(SomeEnum)); .

Warum ist die Syntax so?!

El static Methode GetValues wurde bereits in den alten .NET 1.0 Tagen eingeführt. Sie gibt ein eindimensionales Array vom Laufzeittyp SomeEnum[] . Da es sich aber um eine nicht-generische Methode handelt (Generika wurden erst mit .NET 2.0 eingeführt), kann sie ihren Rückgabetyp (Rückgabetyp zur Kompilierzeit) nicht als solchen deklarieren.

.NET-Arrays haben eine Art von Kovarianz, aber weil SomeEnum wird ein Werttyp und da die Array-Typ-Kovarianz nicht mit Werttypen funktioniert, konnten sie nicht einmal den Rückgabetyp als object[] o Enum[] . (Dies ist ein Unterschied zu z. B. diese Überlast an GetCustomAttributes von .NET 1.0 die zur Kompilierzeit den Rückgabetyp object[] gibt aber tatsächlich ein Array vom Typ SomeAttribute[] donde SomeAttribute ist notwendigerweise ein Referenztyp).

Aus diesem Grund musste die .NET 1.0-Methode ihren Rückgabetyp wie folgt deklarieren System.Array . Aber ich garantiere Ihnen, es ist ein SomeEnum[] .

Jedes Mal, wenn Sie anrufen GetValues wieder mit demselben Aufzählungstyp, muss es ein neues Array zuweisen und die Werte in das neue Array kopieren. Das liegt daran, dass Arrays durch den "Verbraucher" der Methode verändert werden können, so dass ein neues Array erstellt werden muss, um sicherzustellen, dass die Werte unverändert bleiben. In .NET 1.0 gab es keine guten schreibgeschützten Sammlungen.

Wenn Sie die Liste aller Werte an vielen verschiedenen Stellen benötigen, sollten Sie den Aufruf GetValues nur einmal zu verwenden und das Ergebnis in einem schreibgeschützten Wrapper zwischenzuspeichern, zum Beispiel so:

public static readonly ReadOnlyCollection<SomeEnum> AllSomeEnumValues
    = Array.AsReadOnly((SomeEnum[])Enum.GetValues(typeof(SomeEnum)));

Dann können Sie AllSomeEnumValues und dieselbe Sammlung kann sicher wiederverwendet werden.

Warum ist es schlecht, die .Cast<SomeEnum>() ?

Viele andere Antworten verwenden .Cast<SomeEnum>() . Das Problem dabei ist, dass es die nicht-generische IEnumerable Umsetzung der Array Klasse. Diese debe jeden der Werte in ein Feld mit der Bezeichnung System.Object und dann mit Hilfe des Feldes Cast<> Methode, um alle diese Werte wieder zu entpacken. Glücklicherweise ist die .Cast<> Methode scheint den Laufzeittyp ihrer IEnumerable Parameter (der this Parameter), bevor es mit der Iteration durch die Sammlung beginnt, also ist es doch nicht so schlimm. Es stellt sich heraus .Cast<> lässt die gleiche Array-Instanz durch.

Wenn Sie es verfolgen, indem Sie .ToArray() o .ToList() , wie in:

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList() // DON'T do this

haben Sie ein weiteres Problem: Sie erstellen eine neue Sammlung (Array), wenn Sie GetValues und erstellen Sie dann eine neue Sammlung ( List<> ) mit dem .ToList() anrufen. Das ist also eine (zusätzliche) redundante Zuweisung einer ganzen Sammlung, um die Werte zu speichern.


Update: Seit .NET 5.0 (ab 2020) sind die obigen Informationen veraltet; es gibt endlich eine generische Methode (Generics wurden mit .NET Framework 2.0 aus dem Jahr 2005 eingeführt), so dass Sie jetzt einfach verwenden sollten:

Enum.GetValues<SomeEnum>()

deren Rückgabeparameter stark typisiert ist (als SomeEnum[] ).

64voto

Booster2ooo Punkte 1273

Hier ist der Weg, den ich liebe, mit LINQ:

public class EnumModel
{
    public int Value { get; set; }
    public string Name { get; set; }
}

public enum MyEnum
{
    Name1=1,
    Name2=2,
    Name3=3
}

public class Test
{
        List<EnumModel> enums = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Select(c => new EnumModel() { Value = (int)c, Name = c.ToString() }).ToList();

        // A list of Names only, does away with the need of EnumModel 
        List<string> MyNames = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Select(c => c.ToString()).ToList();

        // A list of Values only, does away with the need of EnumModel 
        List<int> myValues = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Select(c => (int)c).ToList();

        // A dictionnary of <string,int>
        Dictionary<string,int> myDic = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).ToDictionary(k => k.ToString(), v => (int)v);
}

Ich hoffe, es hilft

23voto

luisetxenike Punkte 219
List <SomeEnum> theList = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X