2009-01-27 8 views
99

Ich habe den folgenden Code:C# Iterating durch eine Enum? (Indizierung ein System.Array)

// Obtain the string names of all the elements within myEnum 
String[] names = Enum.GetNames(typeof(myEnum)); 

// Obtain the values of all the elements within myEnum 
Array values = Enum.GetValues(typeof(myEnum)); 

// Print the names and values to file 
for (int i = 0; i < names.Length; i++) 
{ 
    print(names[i], values[i]); 
} 

aber ich kann nicht Indexwerte. Gibt es einen einfacheren Weg dies zu tun?

Oder habe ich etwas völlig verpasst!

+0

Vielleicht möchten Sie auschecken [Die Ins und Outs der # Aufzählungen C] (http://www.codeducky.org/ins-outs-c-enums/), die, wie beschrieben, eine typisierte bekommen IEnumerable mit GetValues ​​() und Cast() – ChaseMedallion

Antwort

179
Array values = Enum.GetValues(typeof(myEnum)); 

foreach(MyEnum val in values) 
{ 
    Console.WriteLine (String.Format("{0}: {1}", Enum.GetName(typeof(MyEnum), val), val)); 
} 

Oder können Sie die System.Array gegossen, der zurückgegeben wird:

string[] names = Enum.GetNames(typeof(MyEnum)); 
MyEnum[] values = (MyEnum[])Enum.GetValues(typeof(MyEnum)); 

for(int i = 0; i < names.Length; i++) 
{ 
    print(names[i], values[i]); 
} 

Aber Sie können sicher sein, dass GetValues ​​die Werte in der gleichen Reihenfolge kehrt als GetNames die Namen zurückgibt?

+3

"Aber können Sie sicher sein, dass GetValues ​​die Werte in der gleichen Reihenfolge zurückgibt wie GetNames die Namen zurückgibt?" - Das ist ein sehr guter Punkt und etwas, das ich noch ansprechen muss! Ich denke, Ihre erste Lösung würde wahrscheinlich eine Möglichkeit bieten, um Werte und Strings zuverlässig zu vergleichen. –

+0

Hallo, ich habe schon erwähnt, dass der Verdacht eines "Index-Mismatching" vorkommt, wenn dies geschieht; Ich muss jedoch noch herausfinden, ob dies wirklich ein Problem ist oder nicht? Gibt es bestimmte Fälle, in denen diese Annahme schiefgehen könnte? Danke! – Funka

+0

Sie möchten wahrscheinlich das zweite "val" in ein int umwandeln, wenn Sie Wertkonflikte wie in'Enum.GetName (typeof (MyEnum), val), (int) val) 'behandeln möchten, in denen die Ausgabe die Enumeration bereitstellt Name und Nummer. – Greg

3

Wie wäre es mit einer foreach-Schleife, vielleicht könnten Sie damit arbeiten?

int i = 0; 
    foreach (var o in values) 
    { 
    print(names[i], o); 
    i++; 
    } 

so etwas vielleicht?

+0

Ich habe davon gedacht ... aber ich brauche Zugriff auf beide Namen und Werte in 'Sync' ... sagen die Namen [2] ist gepaart mit Werten [2] und Ich bin unsicher, wie ich das in einer foreach-Schleife erreichen kann! –

+0

Ich habe ein Beispiel hinzugefügt - sehen, ob das hilft. – TWith2Sugars

30

Sie benötigen das Array werfen - das zurückgegebene Array tatsächlich des angeforderten Typs, dh myEnum[], wenn Sie für typeof(myEnum) fragen:

myEnum[] values = (myEnum[]) Enum.GetValues(typeof(myEnum)); 

Dann values[0] etc

8

Sie, dass Array zu verschiedenen werfen können Typen von Arrays:

myEnum[] values = (myEnum[])Enum.GetValues(typeof(myEnum)); 

oder wenn Sie die ganzzahlige Werte wollen:

int[] values = (int[])Enum.GetValues(typeof(myEnum)); 

Sie können diese gegossenen Arrays natürlich iterieren :)

6

Wie wärs mit einem Wörterbuchliste?

und natürlich können Sie den Werttyp des Wörterbuchs ändern, was auch immer Ihre Enum-Werte sind.

+0

Ich denke, dass dies der Weg sein würde, aber leider ist die Enum in einem Bereich von Code, den ich nicht kontrollieren kann! –

2

Array verfügt über eine GetValue (Int32) -Methode, mit der Sie den Wert eines angegebenen Index abrufen können.

Array.GetValue

0

Hier ist eine einfache Möglichkeit, durch Ihr benutzerdefiniertes Objekt Enum

For Each enumValue As Integer In [Enum].GetValues(GetType(MyEnum)) 

    Print([Enum].GetName(GetType(MyEnum), enumValue).ToString) 

Next 
+1

Ich denke OP fragte nach C#. –

4

Hier ist eine andere iterieren. Wir hatten ein Bedürfnis, freundliche Namen für unsere EnumValues ​​anzugeben. Wir haben das System.ComponentModel.DescriptionAttribute verwendet, um einen benutzerdefinierten Zeichenfolgenwert für jeden Enum-Wert anzuzeigen.

public static class StaticClass 
{ 
    public static string GetEnumDescription(Enum currentEnum) 
    { 
     string description = String.Empty; 
     DescriptionAttribute da; 

     FieldInfo fi = currentEnum.GetType(). 
        GetField(currentEnum.ToString()); 
     da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, 
        typeof(DescriptionAttribute)); 
     if (da != null) 
      description = da.Description; 
     else 
      description = currentEnum.ToString(); 

     return description; 
    } 

    public static List<string> GetEnumFormattedNames<TEnum>() 
    { 
     var enumType = typeof(TEnum); 
     if (enumType == typeof(Enum)) 
      throw new ArgumentException("typeof(TEnum) == System.Enum", "TEnum"); 

     if (!(enumType.IsEnum)) 
      throw new ArgumentException(String.Format("typeof({0}).IsEnum == false", enumType), "TEnum"); 

     List<string> formattedNames = new List<string>(); 
     var list = Enum.GetValues(enumType).OfType<TEnum>().ToList<TEnum>(); 

     foreach (TEnum item in list) 
     { 
      formattedNames.Add(GetEnumDescription(item as Enum)); 
     } 

     return formattedNames; 
    } 
} 

In Use

public enum TestEnum 
{ 
     [Description("Something 1")] 
     Dr = 0, 
     [Description("Something 2")] 
     Mr = 1 
} 



    static void Main(string[] args) 
    { 

     var vals = StaticClass.GetEnumFormattedNames<TestEnum>(); 
    } 

Dies wird am Ende "Something 1" Rückkehr "Something 2"

+0

Nur gut, wenn die Beschreibungen statisch sind ... Wenn Ihre Beschreibungen basierend auf einer Instanzbasis geändert werden müssen, dann wird dieser Ansatz nicht funktionieren. – Llyle

4

Eine andere Lösung, mit interessanten Möglichkeiten:

enum Days { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } 

static class Helpers 
{ 
public static IEnumerable<Days> AllDays(Days First) 
{ 
    if (First == Days.Monday) 
    { 
    yield return Days.Monday; 
    yield return Days.Tuesday; 
    yield return Days.Wednesday; 
    yield return Days.Thursday; 
    yield return Days.Friday; 
    yield return Days.Saturday; 
    yield return Days.Sunday; 
    } 

    if (First == Days.Saturday) 
    { 
    yield return Days.Saturday; 
    yield return Days.Sunday; 
    yield return Days.Monday; 
    yield return Days.Tuesday; 
    yield return Days.Wednesday; 
    yield return Days.Thursday; 
    yield return Days.Friday; 
    } 
} 
+2

Mentale Notiz: Verwenden Sie mehr Ausbeute –

2

Sie können vereinfachen dies mit Formatzeichenfolgen. Ich verwende den folgenden Code-Schnipsel in Benutzungsmitteilungen:

writer.WriteLine("Exit codes are a combination of the following:"); 
foreach (ExitCodes value in Enum.GetValues(typeof(ExitCodes))) 
{ 
    writer.WriteLine(" {0,4:D}: {0:G}", value); 
} 

Der D Formatbezeichner formatiert den ENUM-Wert als Dezimalzahl. Es gibt auch einen X-Spezifizierer, der hexadezimale Ausgabe liefert.

Der G-Spezifizierer formatiert eine Aufzählung als Zeichenfolge. Wenn das Flags-Attribut auf die Enumeration angewendet wird, werden auch kombinierte Werte unterstützt. Es gibt einen F-Spezifizierer, der so wirkt, als ob Flags immer vorhanden sind.

Siehe Enum.Format().

3

Alte Frage, aber ein wenig sauberer Ansatz der Verwendung von LINQ .Cast<>()

var values = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>(); 

foreach(var val in values) 
{ 
    Console.WriteLine("Member: {0}",val.ToString());  
} 
2

In den Enum.GetValues ​​Ergebnissen, zu int Gießen erzeugt den numerischen Wert. ToString() erzeugt den angezeigten Namen. Es sind keine weiteren Aufrufe von Enum.GetName erforderlich.

public enum MyEnum 
{ 
    FirstWord, 
    SecondWord, 
    Another = 5 
}; 

// later in some method 

StringBuilder sb = new StringBuilder(); 
foreach (var val in Enum.GetValues(typeof(MyEnum))) { 
    int numberValue = (int)val; 
    string friendyName = val.ToString(); 
    sb.Append("Enum number " + numberValue + " has the name " + friendyName + "\n"); 
} 
File.WriteAllText(@"C:\temp\myfile.txt", sb.ToString()); 

// Produces the output file contents: 
/* 
Enum number 0 has the name FirstWord 
Enum number 1 has the name SecondWord 
Enum number 5 has the name Another 
*/