Das Iterieren über alle Werte eines Enums ist eine häufige Anforderung in C#. Sie müssen möglicherweise ein Dropdown-Menü füllen, Eingaben validieren oder eine Aktion für jedes Enum-Mitglied ausführen. Dieser Leitfaden behandelt alle Ansätze zum Iterieren durch Enums, einschließlich generischer Hilfsmethoden und dem Umgang mit Flags-Enums.

Definition eines Beispiel-Enums

Alle Beispiele in diesem Artikel verwenden das folgende Enum:

public enum Season
{
    Spring,
    Summer,
    Autumn,
    Winter
}

Methode 1: Enum.GetValues mit foreach

Der gebräuchlichste Ansatz verwendet Enum.GetValues, das ein Array aller im Enum definierten Werte zurückgibt:

foreach (Season season in Enum.GetValues(typeof(Season)))
{
    Console.WriteLine(season);
}

Ausgabe:

Spring
Summer
Autumn
Winter

Die Umwandlung vom zurückgegebenen Array zu Season erfolgt implizit, wenn Sie die Schleifenvariable mit dem Enum-Typ deklarieren.

Methode 2: Generisches Enum.GetValues (.NET 5+)

Ab .NET 5 ist eine generische Überladung verfügbar, die ein stark typisiertes Array zurückgibt und die Notwendigkeit von typeof eliminiert:

foreach (Season season in Enum.GetValues<Season>())
{
    Console.WriteLine(season);
}

Dies ist der sauberste Ansatz für moderne .NET-Anwendungen.

Methode 3: Enum.GetNames

Wenn Sie nur die String-Namen der Enum-Mitglieder benötigen, verwenden Sie Enum.GetNames:

foreach (string name in Enum.GetNames(typeof(Season)))
{
    Console.WriteLine(name);
}

Oder mit der generischen Überladung (.NET 5+):

foreach (string name in Enum.GetNames<Season>())
{
    Console.WriteLine(name);
}

Dies gibt dieselben Strings zurück, die Sie erhalten würden, wenn Sie .ToString() auf jedem Enum-Wert aufrufen, aber ohne den Overhead von Boxing und Unboxing.

Methode 4: LINQ mit Enum-Werten

Sie können LINQ verwenden, um Enum-Werte zu filtern, sortieren oder transformieren:

var warmSeasons = Enum.GetValues<Season>()
    .Where(s => s == Season.Spring || s == Season.Summer)
    .ToList();

foreach (var season in warmSeasons)
{
    Console.WriteLine(season);
}

Ein Dictionary aus einem Enum erstellen

Ein häufiges Muster ist das Erstellen eines Wörterbuchs, das Integer-Werte auf Namen abbildet:

var seasonDict = Enum.GetValues<Season>()
    .ToDictionary(s => (int)s, s => s.ToString());

// {0: "Spring", 1: "Summer", 2: "Autumn", 3: "Winter"}

Methode 5: Umwandlung in ein Array für Indexzugriff

Wenn Sie auf Enum-Werte per Index zugreifen müssen:

Season[] seasons = (Season[])Enum.GetValues(typeof(Season));
Season third = seasons[2]; // Autumn
int count = seasons.Length; // 4

Oder mit der generischen Version:

Season[] seasons = Enum.GetValues<Season>();

Ein Dropdown-Menü aus einem Enum füllen

Einer der häufigsten realen Anwendungsfälle ist das Füllen eines UI-Steuerelements:

// Windows Forms ComboBox
comboBox.DataSource = Enum.GetValues<Season>();

// ASP.NET MVC SelectList
var items = Enum.GetValues<Season>()
    .Select(s => new SelectListItem
    {
        Value = ((int)s).ToString(),
        Text = s.ToString()
    })
    .ToList();

Strings zu Enum-Werten parsen

Um einen String in einen Enum-Wert umzuwandeln, verwenden Sie Enum.Parse oder Enum.TryParse:

// Throws ArgumentException if invalid
Season parsed = (Season)Enum.Parse(typeof(Season), "Summer");

// Safe parsing (returns false if invalid)
if (Enum.TryParse<Season>("Summer", out Season result))
{
    Console.WriteLine(result); // Summer
}

// Case-insensitive parsing
Enum.TryParse<Season>("summer", ignoreCase: true, out Season result2);

Konvertierung zwischen Enum und Integer

// Enum to int
int value = (int)Season.Autumn; // 2

// Int to enum
Season season = (Season)2; // Autumn

// Check if value is defined
bool isDefined = Enum.IsDefined(typeof(Season), 2); // true
bool isUndefined = Enum.IsDefined(typeof(Season), 99); // false

Arbeiten mit Flags-Enums

Flags-Enums verwenden das [Flags]-Attribut und bitweise Werte, die Kombinationen ermöglichen:

[Flags]
public enum FilePermissions
{
    None    = 0,
    Read    = 1,
    Write   = 2,
    Execute = 4,
    All     = Read | Write | Execute
}

Einzelne Flags iterieren

Enum.GetValues gibt alle definierten Werte zurück, einschließlich Kombinationen wie All. Um nur die einzelnen Flags zu iterieren, die auf einem gegebenen Wert gesetzt sind:

FilePermissions perms = FilePermissions.Read | FilePermissions.Write;

foreach (FilePermissions flag in Enum.GetValues<FilePermissions>())
{
    if (flag != FilePermissions.None && perms.HasFlag(flag))
    {
        Console.WriteLine(flag);
    }
}
// Output: Read, Write

Einzelne Flags überprüfen

FilePermissions perms = FilePermissions.Read | FilePermissions.Execute;

bool canRead = perms.HasFlag(FilePermissions.Read);       // true
bool canWrite = perms.HasFlag(FilePermissions.Write);     // false
bool canExecute = perms.HasFlag(FilePermissions.Execute); // true

Generische Hilfsmethoden

Sie können wiederverwendbare Hilfsmethoden für Enum-Operationen erstellen:

public static class EnumHelper
{
    /// <summary>
    /// Gets all values of an enum as a typed list.
    /// </summary>
    public static List<T> GetAllValues<T>() where T : struct, Enum
    {
        return Enum.GetValues<T>().ToList();
    }

    /// <summary>
    /// Gets a dictionary mapping enum names to values.
    /// </summary>
    public static Dictionary<string, T> GetNameValuePairs<T>() where T : struct, Enum
    {
        return Enum.GetValues<T>()
            .ToDictionary(e => e.ToString(), e => e);
    }

    /// <summary>
    /// Safely parses a string to an enum, returning a default value if parsing fails.
    /// </summary>
    public static T ParseOrDefault<T>(string value, T defaultValue = default)
        where T : struct, Enum
    {
        return Enum.TryParse<T>(value, ignoreCase: true, out T result)
            ? result
            : defaultValue;
    }
}

Verwendung:

List<Season> allSeasons = EnumHelper.GetAllValues<Season>();
Season parsed = EnumHelper.ParseOrDefault<Season>("summer", Season.Spring);

Kurzreferenz

AufgabeMethode
Alle Werte iterierenEnum.GetValues<T>()
Alle Namen iterierenEnum.GetNames<T>()
String zu Enum parsenEnum.TryParse<T>(string, out T)
Enum zu int(int)enumValue
Int zu Enum(T)intValue
Prüfen ob Wert definiert istEnum.IsDefined(typeof(T), value)
Prüfen ob ein Flag gesetzt istvalue.HasFlag(flag)

Zusammenfassung

Der einfachste Weg, durch ein Enum in C# zu iterieren, ist foreach (var value in Enum.GetValues<T>()) ab .NET 5, oder Enum.GetValues(typeof(T)) bei älteren Frameworks. Verwenden Sie Enum.GetNames, wenn Sie nur die String-Namen benötigen, und verwenden Sie das [Flags]-Attribut mit HasFlag für bitweise Enum-Kombinationen. Für wiederverwendbaren Code erstellen Sie generische Hilfsmethoden mit der Einschränkung where T : struct, Enum.