web-dev-qa-db-fra.com

C # Itérant à travers une énumération? (Indexation d'un System.Array)

J'ai le code suivant:

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

Cependant, je ne peux pas indexer les valeurs. Y a-t-il un moyen plus facile de faire cela? 

Ou ai-je complètement raté quelque chose!

104
TK.
Array values = Enum.GetValues(typeof(myEnum));

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

Ou, vous pouvez convertir le System.Array qui est renvoyé:

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

Mais pouvez-vous être sûr que GetValues ​​renvoie les valeurs dans le même ordre que GetNames renvoie les noms?

187
Frederik Gheysels

Vous devez lancer le tableau - le tableau retourné est en fait du type demandé, à savoir myEnum[] si vous demandez typeof(myEnum):

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

Alors values[0] etc

31
Marc Gravell

Vous pouvez lancer ce tableau sur différents types de tableaux:

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

ou si vous voulez les valeurs entières:

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

Vous pouvez bien sûr itérer ces tableaux castés :)

8
Arcturus

Que diriez-vous d'une liste de dictionnaire?

Dictionary<string, int> list = new Dictionary<string, int>();
foreach( var item in Enum.GetNames(typeof(MyEnum)) )
{
    list.Add(item, (int)Enum.Parse(typeof(MyEnum), item));
}

et bien sûr, vous pouvez changer le type de valeur du dictionnaire en fonction de vos valeurs enum.

7
mrtaikandi

Une autre solution, avec des possibilités intéressantes:

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;
  } 
}
5
Paul

En voici un autre. Nous avions besoin de fournir des noms conviviaux pour nos EnumValues. Nous avons utilisé System.ComponentModel.DescriptionAttribute pour afficher une valeur de chaîne personnalisée pour chaque valeur enum. 

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

Utilisé

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



    static void Main(string[] args)
    {

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

Cela finira par retourner "Quelque chose 1", "Quelque chose 2"

4
Kevin Castle

Ancienne question, mais approche légèrement plus propre en utilisant le .Cast<>() de LINQ 

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

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

Et si vous utilisiez une boucle foreach, vous pourriez peut-être travailler avec ça?

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

quelque chose comme ça peut-être?

3
TWith2Sugars

Dans les résultats Enum.GetValues, la conversion en int génère la valeur numérique. L'utilisation de ToString () produit le nom convivial. Aucun autre appel à Enum.GetName n'est nécessaire.

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
 */
2
Mike Wodarczyk

Vous pouvez simplifier cela en utilisant des chaînes de format. J'utilise l'extrait suivant dans les messages d'utilisation:

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

Le spécificateur de format D formate la valeur enum sous forme décimale. Il existe également un spécificateur X qui donne une sortie hexadécimale.

Le spécificateur G formate une énumération en tant que chaîne. Si l'attribut Flags est appliqué à l'énumération, les valeurs combinées sont également prises en charge. Il existe un spécificateur F qui agit comme si les indicateurs étaient toujours présents.

Voir Enum.Format ().

2
Frank Szczerba

Array a une méthode GetValue (Int32) que vous pouvez utiliser pour extraire la valeur à un index spécifié.

Array.GetValue

2
Bubblewrap

Ancienne question, mais la réponse de 3Dave a fourni l'approche la plus simple. J'avais besoin d'une petite méthode d'assistance pour générer un script SQL afin de décoder une valeur enum dans la base de données pour le débogage. Cela a bien fonctionné:

    public static string EnumToCheater<T>() {
        var sql = "";
        foreach (var enumValue in Enum.GetValues(typeof(T)))
            sql += $@"when {(int) enumValue} then '{enumValue}' ";
        return $@"case ?? {sql}else '??' end,";
    }

Je l'ai dans une méthode statique, donc l'utilisation est:

var cheater = MyStaticClass.EnumToCheater<MyEnum>()
0
Wade Hatler

Voici un moyen simple de parcourir votre objet Enum personnalisé

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

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

Next
0
Chev