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
| Aufgabe | Methode |
|---|---|
| Alle Werte iterieren | Enum.GetValues<T>() |
| Alle Namen iterieren | Enum.GetNames<T>() |
| String zu Enum parsen | Enum.TryParse<T>(string, out T) |
| Enum zu int | (int)enumValue |
| Int zu Enum | (T)intValue |
| Prüfen ob Wert definiert ist | Enum.IsDefined(typeof(T), value) |
| Prüfen ob ein Flag gesetzt ist | value.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.