Numero totale di elementi definiti in un enum


318

Come posso ottenere il numero di elementi definiti in una enum?

Risposte:


430

È possibile utilizzare il metodo statico Enum.GetNamesche restituisce un array che rappresenta i nomi di tutti gli elementi nell'enum. La proprietà length di questo array è uguale al numero di elementi definiti nell'enum

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

1
D'accordo ... ecco un link che ho trovato csharp411.com/c-count-items-in-an-enum
Utente SO

8
Potrebbe anche usare Enum.GetValues.
Xonatron,

6
System.Enum.GetNames, se non si sta già includendo lo spazio dei nomi di sistema.
Brett Pennings,

4
Quindi oggi ho riscontrato nuovamente questo problema; il trucco in stile C come descritto nelle altre risposte di seguito è elencato come problematico, ma sia Enum.GetValues ​​che Enum.GetNames come elencati sopra sembrano rischiare di allocare un nuovo array solo per ottenere una lunghezza fissa, che sembra ... beh , orribile. Qualcuno sa se questo approccio comporta effettivamente un'allocazione dinamica? In tal caso, per alcuni casi d'uso sembra di gran lunga la soluzione più efficace se non la più flessibile.
J Trana,

174

La domanda è:

Come posso ottenere il numero di elementi definiti in una enum?

Il numero di "articoli" potrebbe davvero significare due cose completamente diverse. Considera il seguente esempio.

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

Qual è il numero di "elementi" definiti in MyEnum?

Il numero di articoli è 5? ( A, B, C, D, E)

O è 3? ( 1, 2, 3)

Il numero di nomi definiti in MyEnum(5) può essere calcolato come segue.

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

Il numero di valori definiti in MyEnum(3) può essere calcolato come segue.

var valuesCount = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Distinct().Count();

2
Modo alternativo di scrivere l'ultima riga var valuesCount = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).Distinct().Count();,.
Jeppe Stig Nielsen,

3
Non riesco a pensare a nessuno sviluppatore che abbia mai incontrato in vita mia che affermerebbe che un tale enum contiene 3 elementi.
motoDrizzt,

2
@motoDrizzt puoi trovare qualcosa del genere in un enum di un driver della stampante come Default = 1, A4 = 1, Portrate = 1, A4Portrait = 1, Landscape = 2, A4Landscape = 2, ...;).
shA.t


14

Un trucco ingegnoso che ho visto in una risposta C a questa domanda, basta aggiungere un ultimo elemento all'enum e usarlo per dire quanti elementi ci sono nell'enum:

enum MyType {
  Type1,
  Type2,
  Type3,
  NumberOfTypes
}

Nel caso in cui si definisca un valore iniziale diverso da 0, è possibile utilizzare NumberOfTypes - Type1 per accertare il numero di elementi.

Non sono sicuro se questo metodo sarebbe più veloce dell'utilizzo di Enum e non sono sicuro che sarebbe considerato il modo corretto per farlo, dal momento che abbiamo Enum per verificare queste informazioni per noi.


1
è bello dato che posso farlo su XNA perché GetNames non è disponibile lì
Thiago Valle,

Fantastico trucco, questo sarebbe anche più veloce di GetNames () perché non deve contarli.
Jordan LaPrise,

4
Fai attenzione al codice che scorre attraverso gli enum via foreach: puoi leggere la fine delle tue matrici!
Michael Dorgan,

4
Inoltre, fai attenzione agli enum che definiscono i loro valori: uso spesso gli enum per i bit flag.
Matt Parkins,

1
Fai anche attenzione ai collegamenti enum diretti ad alcuni controlli wpf come combobox e listbox
mcy

6

Dalle risposte precedenti basta aggiungere un esempio di codice.

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

5

Puoi usare Enum.GetNames per restituire un IEnumerable di valori nel tuo enum e quindi. Conta l'IEnumerable risultante.

GetNames produce quasi lo stesso risultato di GetValues ​​ma è più veloce.


5

Se ti ritrovi a scrivere la soluzione sopra tutte le volte che posso, allora potresti implementarla come un generico:

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

1

Lo stavo esaminando proprio ora e non ero contento della leggibilità della soluzione attuale. Se stai scrivendo codice in modo informale o su un piccolo progetto, puoi semplicemente aggiungere un altro elemento alla fine del tuo enum chiamato "Lunghezza". In questo modo, devi solo digitare:

var namesCount = (int)MyEnum.Length;

Ovviamente se altri useranno il tuo codice - o sono sicuro in molte altre circostanze che non mi riguardano in questo caso - questa soluzione può essere ovunque da mal consigliata a terribile.


2
Questo si basa anche sull'enum che inizia da 0 (impostazione predefinita, ma non è affatto garantita). Inoltre, rende l'intellisenso per il normale uso dell'enum molto confuso. Questa è quasi sempre un'idea terribile .
BradleyDotNET,

2
Non ci volle molto :)
EnergyWasRaw,

1
Interessante, suppongo che non saprai mai quando potrebbe accadere qualcosa di meglio. Ho fatto del mio meglio per evitare la mia soluzione, ma l'ho trovato abbastanza interessante da condividere!
EnergyWasRaw,

1

Per Visual Basic:

[Enum].GetNames(typeof(MyEnum)).Lengthnon ha funzionato con me, ma [Enum].GetNames(GetType(Animal_Type)).lengthha funzionato.


Perché il downvote? Questo risolto il mio problema, è la sintassi corretta per VB, anche se la domanda è taggata c #, ancora utile.
M Granja,

2
I voti negativi probabilmente perché la domanda è taggata C # e questa risposta non ha menzionato che non stava usando C #.
idbrii,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.