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

148voto

sircodesalot Punkte 10911

Verwenden Sie Cast<T> :

var suits = Enum.GetValues(typeof(Suit)).Cast<Suit>();

Das war's, IEnumerable<Suit> .

2 Stimmen

Dies funktioniert auch in der from Klausel und die foreach Kopfzeilendeklarator.

0 Stimmen

Die "Cast"-Api erfordert System.Linq. Ich war gerade kurz vor cast.

113voto

James Punkte 5021

Ich denke, dies ist effizienter als andere Vorschläge, weil GetValues() wird nicht jedes Mal aufgerufen, wenn Sie eine Schleife haben. Außerdem ist es übersichtlicher. Und Sie erhalten einen Kompilierfehler und keine Laufzeitausnahme, wenn Suit ist kein enum .

EnumLoop<Suit>.ForEach((suit) => {
    DoSomethingWith(suit);
});

EnumLoop hat diese völlig generische Definition:

class EnumLoop<Key> where Key : struct, IConvertible {
    static readonly Key[] arr = (Key[])Enum.GetValues(typeof(Key));
    static internal void ForEach(Action<Key> act) {
        for (int i = 0; i < arr.Length; i++) {
            act(arr[i]);
        }
    }
}

9 Stimmen

Seien Sie vorsichtig bei der Verwendung von Generika wie diesem. Wenn Sie versuchen, die EnumLoop mit einem Typ, der keine Aufzählung ist, lässt sich gut kompilieren, löst aber zur Laufzeit eine Ausnahme aus.

10 Stimmen

Vielen Dank, Svick. Laufzeitausnahmen werden tatsächlich mit den anderen Antworten auf dieser Seite auftreten... außer dieser, weil ich "where Key : struct, IConvertible" hinzugefügt habe, so dass Sie einen Kompilierzeitfehler in den meisten Fällen erhalten.

5 Stimmen

Nein, GetValues() wird nur einmal in der foreach aufgerufen.

90voto

Aubrey Taylor Punkte 861

Sie erhalten keine Enum.GetValues() in Silberlicht .

Original-Blog-Beitrag von Einar Ingebrigtsen :

public class EnumHelper
{
    public static T[] GetValues<T>()
    {
        Type enumType = typeof(T);

        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<T> values = new List<T>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add((T)value);
        }

        return values.ToArray();
    }

    public static object[] GetValues(Type enumType)
    {
        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<object> values = new List<object>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add(value);
        }

        return values.ToArray();
    }
}

0 Stimmen

Ich bin mit .NET Framework 4.0 & Silverlight enum.getvalues Arbeit, der Code, den ich verwendet wird ---> enum.GetValues(typeof(enum))

2 Stimmen

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

72voto

Tom Carr Punkte 1339

Ich denke, Sie können Folgendes verwenden

Enum.GetNames(Suit)

70voto

Mallox Punkte 1404

Meine Lösung funktioniert in .NET Compact Framework (3.5) und unterstützt die Typenprüfung zur Kompilierzeit :

public static List<T> GetEnumValues<T>() where T : new() {
    T valueType = new T();
    return typeof(T).GetFields()
        .Select(fieldInfo => (T)fieldInfo.GetValue(valueType))
        .Distinct()
        .ToList();
}

public static List<String> GetEnumNames<T>() {
    return typeof (T).GetFields()
        .Select(info => info.Name)
        .Distinct()
        .ToList();
}
  • Wenn jemand weiß, wie man die T valueType = new T() Ich würde mich freuen, eine Lösung zu sehen.

Ein Anruf würde folgendermaßen aussehen:

List<MyEnum> result = Utils.GetEnumValues<MyEnum>();

4 Stimmen

Was ist mit der Verwendung von T valueType = default(T) ?

0 Stimmen

Toll, dieses Stichwort kannte ich noch gar nicht. Es ist immer schön, etwas Neues zu lernen. Ich danke Ihnen! Wird immer ein Verweis auf dasselbe Objekt zurückgegeben, oder wird bei jedem Aufruf der Standardanweisung eine neue Instanz erstellt? Ich habe im Netz bisher nichts darüber gefunden, aber wenn jedes Mal eine neue Instanz erzeugt wird, verfehlt das irgendwie den Zweck, nach dem ich gesucht habe (einen Einzeiler zu haben ^^).

3 Stimmen

Würde dadurch nicht bei jeder Iteration über die Aufzählung eine neue Instanz erzeugt?

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