771 votes

Comment convertir un enum en liste en C# ?

Existe-t-il un moyen de convertir un enum à une liste qui contient toutes les options de l'enum ?

1337voto

Jake Pearson Points 9657

Cela renverra un IEnumerable<SomeEnum> de toutes les valeurs d'un Enum.

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();

Si vous voulez que ce soit un List<SomeEnum> il suffit d'ajouter .ToList() après .Cast<SomeEnum>() .

Pour utiliser la fonction Cast sur un tableau, vous devez disposer de l'attribut System.Linq dans votre section d'utilisation.

137voto

Gili Points 271

C'est beaucoup plus facile :

Enum.GetValues(typeof(SomeEnum))
    .Cast<SomeEnum>()
    .Select(v => v.ToString())
    .ToList();

122voto

Jeppe Stig Nielsen Points 17887

La réponse courte est : utiliser :

(SomeEnum[])Enum.GetValues(typeof(SomeEnum))

Si vous avez besoin de cela pour une variable locale, c'est var allSomeEnumValues = (SomeEnum[])Enum.GetValues(typeof(SomeEnum)); .

Pourquoi la syntaxe est comme ça ? !

Le site static méthode GetValues a été introduit à l'époque de la version 1.0 de .NET. Il renvoie un tableau unidimensionnel de type runtime SomeEnum[] . Mais comme il s'agit d'une méthode non générique (la générique n'a pas été introduite avant .NET 2.0), elle ne peut pas déclarer son type de retour (type de retour au moment de la compilation) en tant que tel.

Les tableaux de .NET ont une sorte de covariance, mais parce que SomeEnum sera un type de valeur et comme la covariance des types de tableaux ne fonctionne pas avec les types de valeurs, ils n'ont même pas pu déclarer le type de retour en tant que object[] ou Enum[] . (Ceci est différent de e.g. cette surcharge de GetCustomAttributes à partir de .NET 1.0 qui a un type de retour au moment de la compilation object[] mais renvoie en fait un tableau de type SomeAttribute[]SomeAttribute est nécessairement un type de référence).

Pour cette raison, la méthode .NET 1.0 devait déclarer son type de retour comme étant System.Array . Mais je vous garantis que c'est un SomeEnum[] .

Chaque fois que vous appelez GetValues avec le même type d'enum, elle devra allouer un nouveau tableau et copier les valeurs dans le nouveau tableau. En effet, les tableaux peuvent être écrits (modifiés) par le "consommateur" de la méthode, qui doit donc créer un nouveau tableau pour s'assurer que les valeurs restent inchangées. .NET 1.0 ne disposait pas de bonnes collections en lecture seule.

Si vous avez besoin de la liste de toutes les valeurs à plusieurs endroits différents, pensez à appeler GetValues une seule fois et mettre en cache le résultat dans un wrapper en lecture seule, par exemple comme ceci :

public static readonly ReadOnlyCollection<SomeEnum> AllSomeEnumValues
    = Array.AsReadOnly((SomeEnum[])Enum.GetValues(typeof(SomeEnum)));

Vous pouvez alors utiliser AllSomeEnumValues plusieurs fois, et la même collection peut être réutilisée en toute sécurité.

Pourquoi est-ce mauvais d'utiliser .Cast<SomeEnum>() ?

Beaucoup d'autres réponses utilisent .Cast<SomeEnum>() . Le problème, c'est qu'elle utilise la fonction non générique IEnumerable mise en œuvre de la Array classe. Ce site devrait a impliqué la mise en boîte de chacune des valeurs dans une System.Object puis en utilisant l'option Cast<> pour débloquer toutes ces valeurs à nouveau. Heureusement, la méthode .Cast<> semble vérifier le type d'exécution de sa méthode IEnumerable (le paramètre this ) avant de commencer à itérer dans la collection, donc ce n'est pas si mal après tout. Il s'avère que .Cast<> laisse passer la même instance de tableau.

Si vous le suivez en .ToArray() ou .ToList() comme dans :

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList() // DON'T do this

vous avez un autre problème : vous créez une nouvelle collection (tableau) lorsque vous appelez GetValues et ensuite créer encore une nouvelle collection ( List<> ) avec le .ToList() appel. Il s'agit donc d'une allocation (supplémentaire) redondante d'une collection entière pour contenir les valeurs.

64voto

Booster2ooo Points 51

Voici la méthode que j'aime, en utilisant LINQ :

public class EnumModel
{
    public int Value { get; set; }
    public string Name { get; set; }
}

public enum MyEnum
{
    Name1=1,
    Name2=2,
    Name3=3
}

public class Test
{
    List<EnumModel> enums = ((IEnumerable<EnumModel>)Enum.GetValues(typeof(MyEnum))).Select(c => new EnumModel() { Value = (int)c, Name = c.ToString() }).ToList();
}

J'espère que cela vous aidera

23voto

luisetxenike Points 181
List <SomeEnum> theList = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X