c# liste d'une taille Comment énumérer une énumération en C #?




13 Answers

Il me semble que vous voulez vraiment imprimer les noms de chaque énumération, plutôt que les valeurs. Dans ce cas, Enum.GetNames() semble être la bonne approche.

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

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

En passant, incrémenter la valeur n'est pas un bon moyen d'énumérer les valeurs d'une énumération. Vous devriez le faire à la place.

Je voudrais utiliser Enum.GetValues(typeof(Suit)) place.

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

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

Comment pouvez-vous énumérer une enum en C #?

Par exemple, le code suivant ne compile pas:

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

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

Et donne l'erreur de compilation suivante:

'Suit' est un 'type' mais est utilisé comme une 'variable'

Il échoue sur le mot-clé Suit , le deuxième.




Certaines versions du framework .NET ne prennent pas en charge Enum.GetValues . Voici une bonne solution à partir d' 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;
}

Comme pour tout code impliquant une reflection , vous devez vous assurer qu'il ne s'exécute qu'une seule fois et que les résultats sont mis en cache.




Pourquoi personne n'utilise Cast<T> ?

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

Là vous allez IEnumerable<Suit> .




Juste pour ajouter ma solution, qui fonctionne dans un cadre compact (3.5) et prend en charge la vérification de type au moment de la compilation :

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

- Si quelqu'un sait comment se débarrasser de T valueType = new T() , je serais heureux de voir une solution.

Un appel ressemblerait à ceci:

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



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



Trois façons:

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

Vous ne savez pas pourquoi GetEnumValues été introduit sur une instance de type, ce n'est pas très lisible du tout pour moi.

Avoir une classe d'assistance comme Enum<T> est ce qui est le plus lisible et le plus mémorable pour moi:

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

Maintenant tu appelles:

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

On peut également utiliser une sorte de cache si les performances comptent, mais je ne m'attends pas à ce que ce soit un problème.

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



J'utilise ToString (), puis divise et analyse le tableau de sélection en indicateurs.

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



Je ne crois pas que cela soit meilleur, ni même bon, simplement énoncer une autre solution.

Si les valeurs enum vont strictement de 0 à n - 1, une alternative générique:

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

Si les valeurs enum sont contiguës et que vous pouvez fournir le premier et le dernier élément de l'énum, ​​alors:

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

mais ce n'est pas strictement énumérant, juste en boucle. La deuxième méthode est beaucoup plus rapide que toute autre approche cependant ...




Voici un exemple de travail de création d'options de sélection pour un 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()
      };



Cette question apparaît dans le chapitre 10 de " C # Step by Step 2013 "

L'auteur utilise une double boucle for pour parcourir une paire d'énumérateurs (afin de créer un jeu de cartes complet):

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

Dans ce cas, Suit et Value sont les deux énumérations:

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

et PlayingCard est un objet de carte avec un Suit et une Value définis:

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

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



Un moyen simple et générique de convertir une énumération en quelque chose que vous pouvez interagir:

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

Et alors:

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



Ajoutez une méthode public static IEnumerable<T> GetValues<T>() à votre classe, comme

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

appelle et passe ton enum, tu peux maintenant le parcourir en utilisant foreach

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



enum types enum sont appelés "types d'énumération" non pas parce qu'ils sont des conteneurs qui "énumèrent" des valeurs (ce qu'ils ne sont pas), mais parce qu'ils sont définis en énumérant les valeurs possibles pour une variable de ce type.

(En fait, c'est un peu plus compliqué que cela - les types enum sont considérés comme ayant un type entier "sous-jacent", ce qui signifie que chaque valeur enum correspond à une valeur entière (ceci est généralement implicite, mais peut être spécifié manuellement). C # a été conçu de manière à pouvoir insérer n'importe quel entier de ce type dans la variable enum, même s'il ne s'agit pas d'une valeur "nommée".)

La méthode System.Enum.GetNames peut être utilisée pour extraire un tableau de chaînes contenant le nom des valeurs enum, comme son nom l'indique.

EDIT: aurait dû suggérer la méthode System.Enum.GetValues place. Oops.




Related