Frage

Wie kann man eine aufzählen? enum in C#?

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

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

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

Und gibt den folgenden Kompilierzeitfehler aus:

„Anzug“ ist ein „Typ“, wird aber wie eine „Variable“ verwendet.

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

War es hilfreich?

Lösung

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

Hinweis : Die Besetzung zu (Suit[]) ist nicht unbedingt notwendig, aber den Code 0,5 ns schneller machen.

Andere Tipps

Es scheint mir, wie Sie wirklich die Namen der einzelnen ENUM drucken möchten, anstatt die Werte. In diesem Fall Enum.GetNames() scheint der richtige Weg 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);
    }
}

By the way, ist der Wert erhöht wird kein guter Weg, um die Werte eines Aufzählungs aufzuzählen. Sie sollten diese stattdessen tun.

Ich würde Enum.GetValues(typeof(Suit)) anstelle.

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

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

ich einige Erweiterungen für die einfache ENUM Nutzung gemacht, vielleicht jemand kann es verwenden ...

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)
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all items for an enum type.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>() where T : struct
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all combined items from an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <example>
    /// Displays ValueA and ValueB.
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// foreach (var item in dummy.GetAllSelectedItems<EnumExample>())
    /// {
    ///    Console.WriteLine(item);
    /// }
    /// </code>
    /// </example>
    public static IEnumerable<T> GetAllSelectedItems<T>(this Enum value)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);

        foreach (object item in Enum.GetValues(typeof(T)))
        {
            int itemAsInt = Convert.ToInt32(item, CultureInfo.InvariantCulture);

            if (itemAsInt == (valueAsInt & itemAsInt))
            {
                yield return (T)item;
            }
        }
    }

    /// <summary>
    /// Determines whether the enum value contains a specific value.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <param name="request">The request.</param>
    /// <returns>
    ///     <c>true</c> if value contains the specified value; otherwise, <c>false</c>.
    /// </returns>
    /// <example>
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// if (dummy.Contains<EnumExample>(EnumExample.ValueA))
    /// {
    ///     Console.WriteLine("dummy contains EnumExample.ValueA");
    /// }
    /// </code>
    /// </example>
    public static bool Contains<T>(this Enum value, T request)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);
        int requestAsInt = Convert.ToInt32(request, CultureInfo.InvariantCulture);

        if (requestAsInt == (valueAsInt & requestAsInt))
        {
            return true;
        }

        return false;
    }
}

Die ENUM selbst muss mit dem Flags

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}

Einige Versionen des .NET Frameworks unterstützen nicht Enum.GetValues.Hier ist eine gute Problemumgehung von Ideen 2.0:Enum.GetValues ​​im Compact Framework:

public Enum[] GetValues(Enum enumeration)
{
    FieldInfo[] fields = enumeration.GetType().GetFields(BindingFlags.Static | BindingFlags.Public);
    Enum[] enumerations = new Enum[fields.Length];

    for (var i = 0; i < fields.Length; i++)
        enumerations[i] = (Enum) fields[i].GetValue(enumeration);

    return enumerations;
}

Wie bei jedem Code, der dazugehört Betrachtung, sollten Sie Maßnahmen ergreifen, um sicherzustellen, dass es nur einmal ausgeführt wird und die Ergebnisse zwischengespeichert werden.

Warum ist niemand mit Cast<T>?

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

Dort gehen Sie IEnumerable<Suit>.

Ich denke, das als andere Vorschläge effizienter ist, weil GetValues() nicht jedes Mal, wenn Sie eine Schleife haben genannt wird. Es ist auch übersichtlicher. Und Sie erhalten einen Fehler bei der Kompilierung nicht eine Laufzeitausnahme, wenn Suit kein enum ist.

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

EnumLoop hat diese ganz allgemeine 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]);
        }
    }
}

Sie werden nicht Enum.GetValues() in Silverlight erhalten.

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();
    }
}

Nur meine Lösung hinzuzufügen, die in Compact Framework arbeitet (3.5) und unterstützt Typprüfung bei der Kompilierung :

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 der T valueType = new T() loszuwerden, ich würde gerne eine Lösung sehen

Ein Anruf würde wie folgt aussehen:

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

Ich glaube, Sie können

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

Ich habe vage Gerüchte gehört, dass dies   terifically langsam. Weiß jemand? - Orion   Edwards 15. Oktober '08 um 1:31 7

ich denke, das Array des Caching erheblich nach oben beschleunigen würde. Es sieht aus wie Sie ein neues Array bekommen (durch Reflexion) jedes Mal. Vielmehr:

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

Das ist zumindest ein wenig schneller, ja?

Drei Möglichkeiten:

1. Enum.GetValues(type) //since .NET 1.1, not in silverlight or compact framewok
2. type.GetEnumValues() //only on .NET 4 and above
3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) //works everywhere

nicht sicher, warum GetEnumValues wurde auf Typ-Instanz eingeführt, ist es nicht sehr gut lesbar ist überhaupt für mich.


Nachdem eine Hilfsklasse wie Enum<T> ist, was ist am besten lesen und unvergesslich für mich:

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:

Enum<Suit>.GetValues();
//or
Enum.GetValues(typeof(Suit)); //pretty consistent style

Man kann auch eine Art Caching, wenn Leistung zählt, aber ich erwarte nicht, das überhaupt ein Thema sein

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)));
    }
}

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

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));
    }
}

Reinigen einfach und von @ Jeppe-Stig-Nielsen Kommentar der schnell.

Ich benutze ToString () dann aufgeteilt und den Spieß Array in Fahnen analysieren.

[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);
}

Es gibt zwei Möglichkeiten, um eine Enum iterieren:

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

Die erste finden Sie Werte in Form geben auf einer Reihe von object , und die zweite werden Sie Werte in Form von Array von geben String .

Verwenden Sie es in foreach Schleife wie folgt:

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

Ich halte nicht die Meinung, das ist besser, oder sogar gut, nur unter Angabe noch eine andere Lösung.

Wenn ENUM-Werte reichen streng von 0 bis n - 1, 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 ENUM-Werte sind zusammenhängend und Sie können das erste und das letzte Element der Enumeration liefern, dann:

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

aber das ist nicht streng aufzählt, nur Looping. Die zweite Methode ist viel schneller als jeder andere Ansatz though ...

Wenn Sie Geschwindigkeit benötigen und geben Sie bei der Erstellung und der Laufzeit überprüft, diese Hilfsmethode ist besser als LINQ jedes Element zu werfen:

public static T[] GetEnumValues<T>() where T : struct, IComparable, IFormattable, IConvertible
{
    if (typeof(T).BaseType != typeof(Enum))
    {
        throw new ArgumentException(string.Format("{0} is not of type System.Enum", typeof(T)));
    }
    return Enum.GetValues(typeof(T)) as T[];
}

Und Sie können es wie unten verwenden:

static readonly YourEnum[] _values = GetEnumValues<YourEnum>();

Natürlich können Sie IEnumerable<T> zurückkehren, aber das kauft man hier nichts.

Hier ist ein funktionierendes Beispiel für das Erstellen wählen Sie 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()
      };
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}

(Die aktuelle akzeptierte Antwort hat eine Besetzung, die ich glaube nicht, ist erforderlich (obwohl ich falsch sein kann).)

Diese Frage wird in Kapitel 10 von „ C # Schritt für Schritt 2013 "

Der Autor verwendet eine doppelte for-Schleife durch ein Paar von Enumeratoren iterieren (ein vollständiges Kartenspiel 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 Suit und Value sind 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 Karten Objekt mit einer 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;
    }
}

Ich weiß, dass es ein bisschen chaotisch, aber wenn Sie Fan von Einzeiler sind, ist hier ein:

((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));

Was ist, wenn Sie der Typ wissen, wird eine enum sein, aber Sie wissen nicht, was die genaue Art bei der Kompilierung ist?

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

    public static IEnumerable getListOfEnum(Type type)
    {
        MethodInfo getValuesMethod = typeof(EnumHelper).GetMethod("GetValues").MakeGenericMethod(type);
        return (IEnumerable)getValuesMethod.Invoke(null, null);
    }
}

Das Verfahren getListOfEnum verwendet Reflektion jeden Aufzählungstyp zu nehmen und gibt eine IEnumerable alle ENUM-Werte.

Verbrauch:

Type myType = someEnumValue.GetType();

IEnumerable resultEnumerable = getListOfEnum(myType);

foreach (var item in resultEnumerable)
{
    Console.WriteLine(String.Format("Item: {0} Value: {1}",item.ToString(),(int)item));
}

Eine einfache und generische Art und Weise eine Enumeration, um etwas zu konvertieren 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>();

Add-Methode public static IEnumerable<T> GetValues<T>() Ihre Klasse, wie

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

anrufen und Ihre Enum passieren, jetzt können Sie durchlaufen foreach mit

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

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

(Eigentlich ist das etwas komplizierter – bei Enum-Typen wird davon ausgegangen, dass sie einen „zugrunde liegenden“ Integer-Typ haben, was bedeutet, dass jeder Enum-Wert einem Integer-Wert entspricht (dies ist normalerweise implizit, kann aber manuell angegeben werden).C# wurde so konzipiert, dass man alles vollbringen kann beliebig (Integer dieses Typs in die Enum-Variable einfügen, auch wenn es sich nicht um einen „benannten“ Wert handelt.)

Der System.Enum.GetNames-Methode kann verwendet werden, um ein Array von Zeichenfolgen abzurufen, die, wie der Name schon sagt, die Namen der Enum-Werte sind.

BEARBEITEN:Hätte das vorschlagen sollen System.Enum.GetValues Methode statt.Hoppla.

Sie können auch auf die öffentlichen statischen Mitglieder der Enumeration binden direkt durch Reflexion mit:

typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static)
    .ToList().ForEach(x => DoSomething(x.Name));

Versuchen Sie es mit foreach (var item in enum.getValues ​​(Typof (Anzüge)))

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top