[C#] Wie iteriere ich über ein Enum?


Answers

Es sieht für mich so aus, als ob du wirklich die Namen jedes Enums ausdrucken willst, anstatt die Werte. In diesem Fall scheint Enum.GetNames() der richtige Ansatz zu sein.

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

public void PrintAllSuits()
{
    foreach (string name in Enum.GetNames(typeof(Suits)))
    {
        System.Console.WriteLine(name);
    }
}

Übrigens ist das Erhöhen des Werts keine gute Möglichkeit, die Werte einer Enumeration aufzuzählen. Sie sollten dies stattdessen tun.

Ich würde stattdessen Enum.GetValues(typeof(Suit)) verwenden.

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

public void PrintAllSuits()
{
    foreach (var suit in Enum.GetValues(typeof(Suits)))
    {
        System.Console.WriteLine(suit.ToString());
    }
}
Question

Wie können Sie eine enum in C # aufzählen?

ZB kompiliert der folgende Code nicht:

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

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

Und gibt den folgenden Kompilierungsfehler aus:

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

Das Keyword Suit schlägt fehl, das zweite Keyword.




Einige Versionen von .NET Framework unterstützen Enum.GetValues . Hier ist ein guter Workaround von Ideas 2.0: Enum.GetValues ​​in Compact Framework :

public List<Enum> GetValues(Enum enumeration)
{
   List<Enum> enumerations = new List<Enum>();
   foreach (FieldInfo fieldInfo in enumeration.GetType().GetFields(
         BindingFlags.Static | BindingFlags.Public))
   {
      enumerations.Add((Enum)fieldInfo.GetValue(enumeration));
   }
   return enumerations;
}

Wie bei jedem Code mit reflection sollten Sie Schritte unternehmen, um sicherzustellen, dass er nur einmal ausgeführt wird und Ergebnisse zwischengespeichert werden.




Ich benutze ToString () dann split und analysiere das Spit-Array in Flags.

[Flags]
public enum ABC {
   a = 1,
   b = 2,
   c = 4
};

public IEnumerable<ABC> Getselected (ABC flags)
{
   var values = flags.ToString().Split(',');
   var enums = values.Select(x => (ABC)Enum.Parse(typeof(ABC), x.Trim()));
   return enums;
}

ABC temp= ABC.a | ABC.b;
var list = getSelected (temp);
foreach (var item in list)
{
   Console.WriteLine(item.ToString() + " ID=" + (int)item);
}



Eine einfache und generische Methode, um eine Enumeration in etwas zu konvertieren, mit dem Sie interagieren können:

public static Dictionary<int, string> ToList<T>() where T : struct
{
   return ((IEnumerable<T>)Enum
       .GetValues(typeof(T)))
       .ToDictionary(
           item => Convert.ToInt32(item),
           item => item.ToString());
}

Und dann:

var enums = EnumHelper.ToList<MyEnum>();



Warum benutzt niemand Cast<T> ?

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

Da gehst du IEnumerable<Suit> .




Was zum Teufel werde ich meine zwei Pence in werfen, nur durch die Kombination der Top-Antworten durch eine sehr einfache Erweiterung zusammen

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 Enum value)
    {
        return (T[])Enum.GetValues(typeof (T));
    }
}

Einfach und schnell durch @ Jeppe-Stig-Nielsen's Kommentar schnell.




Hier ist ein Arbeitsbeispiel zum Erstellen ausgewählter Optionen für eine DDL

var resman = ViewModelResources.TimeFrame.ResourceManager;

ViewBag.TimeFrames = from MapOverlayTimeFrames timeFrame 
      in Enum.GetValues(typeof(MapOverlayTimeFrames))
      select new SelectListItem
      {
         Value = timeFrame.ToString(),
         Text = resman.GetString(timeFrame.ToString()) ?? timeFrame.ToString()
      };



Nur um meine Lösung hinzuzufügen, die im kompakten Framework (3.5) funktioniert und die Typprüfung zur Kompilierzeit unterstützt :

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 den T valueType = new T() los wird, würde ich mich freuen, eine Lösung zu sehen.

Ein Anruf würde so aussehen:

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



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



Ich bin nicht der Meinung, dass dies besser oder sogar gut ist, sondern nur eine andere Lösung.

Wenn Enum-Werte streng zwischen 0 und n - 1 liegen, ist dies eine generische Alternative:

public void EnumerateEnum<T>()
{
    int length = Enum.GetValues(typeof(T)).Length;
    for (var i = 0; i < length; i++)
    {
        var @enum = (T)(object)i;
    }
}

Wenn Aufzählungswerte zusammenhängend sind und Sie das erste und das letzte Element der Aufzählung bereitstellen können, gilt Folgendes:

public void EnumerateEnum()
{
    for (var i = Suit.Spade; i <= Suit.Diamond; i++)
    {
        var @enum = i;
    }
}

aber das ist nicht genau das Aufzählen, nur Schleifen. Die zweite Methode ist jedoch viel schneller als jede andere Methode ...




Fügen Sie Ihrer Klasse die Methode public static IEnumerable<T> GetValues<T>()

public static IEnumerable<T> GetValues<T>()
{
    return Enum.GetValues(typeof(T)).Cast<T>();
}

Ruf und passiere dein Enum, jetzt kannst du es mit foreach durchlaufen

 public static void EnumerateAllSuitsDemoMethod()
 {
     // custom method
     var foos = GetValues<Suit>(); 
     foreach (var foo in foos)
     {
         // Do something
     }
 }



Diese Frage erscheint in Kapitel 10 von " C # Step by Step 2013 "

Der Autor verwendet eine doppelte For-Schleife, um ein Paar Enumeratoren zu durchlaufen (um ein vollständiges Kartenspiel zu erstellen):

class Pack
{
    public const int NumSuits = 4;
    public const int CardsPerSuit = 13;
    private PlayingCard[,] cardPack;

    public Pack()
    {
        this.cardPack = new PlayingCard[NumSuits, CardsPerSuit];
        for (Suit suit = Suit.Clubs; suit <= Suit.Spades; suit++)
        {
            for (Value value = Value.Two; value <= Value.Ace; value++)
            {
                cardPack[(int)suit, (int)value] = new PlayingCard(suit, value);
            }
        }
    }
}

In diesem Fall sind Suit und Value beide Aufzählungen:

enum Suit { Clubs, Diamonds, Hearts, Spades }
enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace}

und PlayingCard ist ein PlayingCard mit einem definierten Suit und Value :

class PlayingCard
{
    private readonly Suit suit;
    private readonly Value value;

    public PlayingCard(Suit s, Value v)
    {
        this.suit = s;
        this.value = v;
    }
}



enum werden "Aufzählungstypen" genannt, nicht weil sie Container sind, die Werte "aufzählen" (was sie nicht sind), sondern weil sie durch Aufzählung der möglichen Werte für eine Variable dieses Typs definiert sind.

(Tatsächlich ist das ein bisschen komplizierter als das - Enumerationstypen werden als "zugrunde liegender" Integertyp betrachtet, was bedeutet, dass jeder Enumerationswert einem ganzzahligen Wert entspricht (dies ist normalerweise implizit, kann aber manuell spezifiziert werden). C # wurde entworfen in einer Weise, dass Sie jede Ganzzahl dieses Typs in die Enum-Variable stopfen können , auch wenn es kein "benannter" Wert ist.)

Die System.Enum.GetNames-Methode kann verwendet werden, um ein Array von Zeichenfolgen abzurufen, bei denen es sich um die Namen der Enum-Werte handelt, wie der Name vermuten lässt.

EDIT: Sollte stattdessen die System.Enum.GetValues Methode vorgeschlagen haben. Hoppla.




Links