4393 Stimmen

Wie man eine Aufzählung durchführt

Wie können Sie eine Aufzählung von enum in C#?

Der folgende Code lässt sich z. B. nicht kompilieren:

public enum Suit
{
    Spades,
    Hearts,
    Clubs,
    Diamonds
}

public void EnumerateAllSuitsDemoMethod()
{
    foreach (Suit suit in Suit)
    {
        DoSomething(suit);
    }
}

Und es gibt den folgenden Kompilierzeitfehler:

Anzug" ist ein "Typ", wird aber wie eine "Variable" verwendet

Es scheitert an der Suit Schlüsselwort, das zweite.

24 Stimmen

6 Stimmen

Vielleicht möchten Sie sich informieren über die Besonderheiten von C#-Enums in dem dies und andere nützliche Informationen über Enum erörtert werden

60voto

Joshua Drake Punkte 2626
public void PrintAllSuits()
{
    foreach(string suit in Enum.GetNames(typeof(Suits)))
    {
        Console.WriteLine(suit);
    }
}

3 Stimmen

Damit wird eine Zeichenkette aufgezählt. Vergessen Sie nicht, diese Dinge zurück in einen Aufzählungswert zu konvertieren, damit die Aufzählung aufgezählt werden kann.

2 Stimmen

Ich sehe von Ihrem bearbeiten, dass Sie tatsächlich auf die Enums selbst arbeiten möchten, der obige Code adressiert Ihren ursprünglichen Beitrag.

58voto

foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }

Ich habe vage Gerüchte gehört, dass es sich um furchtbar langsam ist. Weiß das jemand? - Orion Edwards 15. Okt '08 um 1:31 7

Ich denke, die Zwischenspeicherung des Arrays würde dies erheblich beschleunigen. Es sieht aus wie Sie ein neues Array (durch Reflexion) jedes Mal erhalten. Stattdessen:

Array enums = Enum.GetValues(typeof(Suit));
foreach (Suit suitEnum in enums) 
{
    DoSomething(suitEnum);
}

Das ist zumindest ein bisschen schneller, ja?

7 Stimmen

Der Compiler sollte sich jedoch darum kümmern.

1 Stimmen

@StephanBijzitter Wow, da liest du aber ganz schön weit unten :-) Ich stimme zu, der Compiler sollte meine Lösung überflüssig machen.

3 Stimmen

Dies ist nicht erforderlich. Wenn man sich den kompilierten Code in ILSpy anschaut, tut der Compiler dies definitiv bereits. Warum wird diese Antwort überhaupt hochgestuft, geschweige denn 35 Mal?

41voto

nawfal Punkte 65966

Drei Möglichkeiten:

  1. Enum.GetValues(type) // Seit .NET 1.1, nicht in Silverlight oder .NET Compact Framework
  2. type.GetEnumValues() // Nur unter .NET 4 und höher
  3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) // Funktioniert überall

Ich bin nicht sicher, warum GetEnumValues wurde für Typ-Instanzen eingeführt. Das ist für mich nicht sehr lesbar.


Mit einer Hilfsklasse wie Enum<T> ist das, was für mich am lesbarsten und einprägsamsten ist:

public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
    public static IEnumerable<T> GetValues()
    {
        return (T[])Enum.GetValues(typeof(T));
    }

    public static IEnumerable<string> GetNames()
    {
        return Enum.GetNames(typeof(T));
    }
}

Jetzt rufen Sie an:

Enum<Suit>.GetValues();

// Or
Enum.GetValues(typeof(Suit)); // Pretty consistent style

Man kann auch eine Art Zwischenspeicherung verwenden, wenn die Leistung wichtig ist, aber ich erwarte nicht, dass dies ein Problem darstellt.

public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
    // Lazily loaded
    static T[] values;
    static string[] names;

    public static IEnumerable<T> GetValues()
    {
        return values ?? (values = (T[])Enum.GetValues(typeof(T)));
    }

    public static IEnumerable<string> GetNames()
    {
        return names ?? (names = Enum.GetNames(typeof(T)));
    }
}

0 Stimmen

Dies ist eine schöne Zusammenfassung der Methoden. Ich denke, Sie sollten Ihre andere Antwort mit dieser zusammenführen. Die Wahrheit ist, dass enum etwas Besonderes sind und das Durchlaufen einer Schleife ist oft (normalerweise) genauso gültig wie enumeration, weil man weiß, dass sich die Werte nie ändern werden. Wenn Sie also eine Aufzählung haben, die sich ständig ändert, dann haben Sie das falsche Datenkonstrukt gewählt.

41voto

Darkside Punkte 1685

Indem ich die wichtigsten Antworten kombinierte, konnte ich eine sehr einfache Erweiterung erstellen:

public static class EnumExtensions
{
    /// <summary>
    /// Gets all items for an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>(this T value) where T : Enum
    {
        return (T[])Enum.GetValues(typeof (T));
    }
}

Es ist sauber, einfach und, wie @Jeppe-Stig-Nielsen schreibt, schnell.

6 Stimmen

Beginnend mit C# 7.3 (Visual Studio 2017 v15.7), kann man where T: Enum

37voto

Kylo Ren Punkte 8048

Es gibt zwei Möglichkeiten der Iteration einer Enum :

1. var values =  Enum.GetValues(typeof(myenum))
2. var values =  Enum.GetNames(typeof(myenum))

Die erste gibt Ihnen Werte in Form eines Arrays von ** object **s, und die zweite gibt Ihnen Werte in Form eines Arrays von ** String **s.

Verwenden Sie es in einem foreach Schleife wie unten:

foreach(var value in values)
{
    // Do operations here
}

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