Nombre total d'éléments définis dans une énumération

318

Comment puis-je obtenir le nombre d'éléments définis dans une énumération?

Utilisateur SO
la source

Réponses:

430

Vous pouvez utiliser la méthode statique Enum.GetNamesqui renvoie un tableau représentant les noms de tous les éléments de l'énumération. La propriété length de ce tableau est égale au nombre d'éléments définis dans l'énumération

var myEnumMemberCount = Enum.GetNames(typeof(MyEnum)).Length;
Kasper Holdum
la source
1
D'accord ... voici un lien que j'ai trouvé csharp411.com/c-count-items-in-an-enum
Utilisateur SO
8
Pourrait également utiliser Enum.GetValues.
Xonatron
6
System.Enum.GetNames, si vous n'incluez pas déjà l'espace de noms System.
Brett Pennings
4
Je viens donc de rencontrer à nouveau ce problème aujourd'hui; l'astuce de style C décrite dans les autres réponses ci-dessous est répertoriée comme problématique, mais les Enum.GetValues ​​et Enum.GetNames énumérés ci-dessus semblent risquer d'allouer un tout nouveau tableau juste pour obtenir une longueur fixe, ce qui semble ... eh bien , horrible. Est-ce que quelqu'un sait si cette approche entraîne effectivement une allocation dynamique? Dans l'affirmative, pour certains cas d'utilisation, elle semble de loin la solution la plus performante sinon la plus flexible.
J Trana
174

La question est:

Comment puis-je obtenir le nombre d'éléments définis dans une énumération?

Le nombre «d'articles» pourrait vraiment signifier deux choses complètement différentes. Prenons l'exemple suivant.

enum MyEnum
{
    A = 1,
    B = 2,
    C = 1,
    D = 3,
    E = 2
}

Quel est le nombre «d'articles» défini dans MyEnum?

Le nombre d'articles est-il 5? ( A, B, C, D, E)

Ou est-ce 3? ( 1, 2, 3)

Le nombre de noms définis en MyEnum(5) peut être calculé comme suit.

var namesCount = Enum.GetNames(typeof(MyEnum)).Length;

Le nombre de valeurs définies en MyEnum(3) peut être calculé comme suit.

var valuesCount = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Distinct().Count();
Timothy Shields
la source
2
Manière alternative d'écrire la dernière ligne var valuesCount = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Distinct().Count();,.
Jeppe Stig Nielsen
3
Je ne peux penser à aucun développeur que j'ai jamais rencontré de ma vie qui affirmerait qu'une telle énumération contient 3 éléments.
motoDrizzt
2
@motoDrizzt vous pouvez trouver quelque chose comme ça dans une énumération d'un pilote d'imprimante comme Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ...;).
shA.t
72

Enum.GetValues (typeof (MyEnum)). Length;

Matt Hamilton
la source
7
Il est plus rapide d'utiliser la méthode GetNames.
Kasper Holdum
Les résultats doivent-ils être mis en cache dans une classe utilitaire?
djmj
14

Une astuce astucieuse que j'ai vue dans une réponse C à cette question, il suffit d'ajouter un dernier élément à l'énumération et de l'utiliser pour dire combien d'éléments sont dans l'énumération:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

Dans le cas où vous définissez une valeur de départ autre que 0, vous pouvez utiliser NumberOfTypes - Type1 pour déterminer le nombre d'éléments.

Je ne sais pas si cette méthode serait plus rapide que d'utiliser Enum, et je ne sais pas non plus si elle serait considérée comme la bonne façon de le faire, car nous avons Enum pour vérifier ces informations pour nous.

Josh
la source
1
c'est bien car je peux le faire sur XNA car GetNames n'est pas disponible là
Thiago Valle
Astuce cool, ce serait également plus rapide que GetNames () car il n'a pas à les compter.
Jordan LaPrise
4
Méfiez-vous du code qui parcourt les énumérations via foreach - vous pouvez lire la fin de vos tableaux!
Michael Dorgan
4
Méfiez-vous également des énumérations qui définissent leurs propres valeurs - j'utilise souvent des énumérations pour les indicateurs de bits.
Matt Parkins
1
Méfiez-vous également des liaisons d'énumération directes à certains contrôles wpf tels que combobox et listbox
mcy
6

À partir des réponses précédentes, il suffit d'ajouter un exemple de code.

 class Program
    {
        static void Main(string[] args)
        {
            int enumlen = Enum.GetNames(typeof(myenum)).Length;
            Console.Write(enumlen);
            Console.Read();
        }
        public enum myenum
        {
            value1,
            value2
        }
    }
jvanderh
la source
5

Vous pouvez utiliser Enum.GetNames pour renvoyer un IEnumerable de valeurs dans votre énumération, puis .Count the IEnumerable résultant.

GetNames produit à peu près le même résultat que GetValues ​​mais est plus rapide.

Lucas Willett
la source
5

Si vous vous retrouvez à écrire la solution ci-dessus aussi souvent que moi, vous pouvez l'implémenter en tant que générique:

public static int GetEnumEntries<T>() where T : struct, IConvertible 
{
    if (!typeof(T).IsEnum)
        throw new ArgumentException("T must be an enumerated type");

    return Enum.GetNames(typeof(T)).Length;
}
Matt Parkins
la source
1

J'étais en train d'examiner cette question tout à l'heure et je n'étais pas satisfait de la lisibilité de la solution actuelle. Si vous écrivez du code de manière informelle ou sur un petit projet, vous pouvez simplement ajouter un autre élément à la fin de votre énumération appelé "Longueur". De cette façon, il vous suffit de taper:

var namesCount = (int)MyEnum.Length;

Bien sûr, si d'autres vont utiliser votre code - ou je suis sûr que dans de nombreuses autres circonstances qui ne s'appliquent pas à moi dans ce cas - cette solution peut être de mal avisée à terrible.

EnergyWasRaw
la source
2
Cela repose également sur l'énumération commençant à 0 (la valeur par défaut, mais nullement garantie). De plus, cela rend l'intellisense pour une utilisation normale de l'énumération très déroutant. C'est presque toujours une idée terrible .
BradleyDotNET
2
Cela n'a pas pris longtemps :)
EnergyWasRaw
1
Intéressant, je suppose que vous ne savez jamais quand quelque chose de mieux peut arriver. J'ai fait de mon mieux pour éviter ma propre solution, mais je l'ai trouvée assez intéressante à partager!
EnergyWasRaw
1

Pour Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Lengthn'a pas travaillé avec moi, mais l'a [Enum].GetNames(GetType(Animal_Type)).lengthfait.

S22
la source
Pourquoi le downvote? Cela a résolu mon problème, c'est la syntaxe correcte pour VB, même si la question est balisée c #, toujours utile.
M Granja
2
Downvotes probablement parce que la question est balisée C # et cette réponse n'a pas mentionné qu'elle n'utilisait pas C #.
idbrii