Come enumerare un enum


3767

Come si può elencare un enumin C #?

Ad esempio, il seguente codice non viene compilato:

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

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

E dà il seguente errore di compilazione:

'Suit' è un 'tipo' ma viene usato come una 'variabile'

Non riesce sulla Suitparola chiave, la seconda.



2
Potresti voler dare un'occhiata ai dettagli di C # enums , che discute di questo e di altre utili notizie
sull'enum

Risposte:


4614
foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit)))
{
}

Nota : il cast a (Suit[])non è strettamente necessario, ma rende il codice 0,5 ns più veloce .


97
Questo non funziona se hai valori duplicati nell'elenco degli enumeratori.
Jessy,

10
Voglio solo sottolineare che questo, sfortunatamente, non funzionerà in Silverlight, dal momento che la libreria Silverlight non comprende enum.GetValues. Devi usare la riflessione in questo caso.
Giacomo Tagliabue,

146
@Jessy questo fa il lavoro in caso di situazioni duplicati come enum E {A = 0, B = 0}. Enum.GetValuescomporta la restituzione di due valori, sebbene siano uguali. E.A == E.Bè vero, quindi non c'è distinzione. Se vuoi singoli nomi, allora dovresti cercare Enum.GetNames.
nawfal,

13
Quindi se hai duplicati / sinonimi nel tuo enum e vuoi l'altro comportamento, puoi usare l' Distinctestensione di Linq (da .NET 3.5), quindi foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }.
Jeppe Stig Nielsen,

42
Ho fatto l'errore di provare a usare varper il tipo. Il compilatore renderà la variabile un Objectanziché l'enum. Elencare il tipo di enum in modo esplicito.
jpmc26,

695

Mi sembra che tu voglia davvero stampare i nomi di ogni enum, piuttosto che i valori. Nel qual caso Enum.GetNames()sembra essere l'approccio giusto.

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

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

A proposito, incrementare il valore non è un buon modo per enumerare i valori di un enum. Dovresti farlo invece.

Vorrei usare Enum.GetValues(typeof(Suit))invece.

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

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

2
Sintassi VB qui: collegamento
AndruWitta,

Ho preso la versione con un piccolo seguito cambia da parte mia: Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray(). In tal caso, posso iterare la matrice di Suitselementi enum, non le stringhe.
Barabas,

@Barabas perché non farlo Suits suit in Enum.GetValues(typeof(Suits))?
risposta

@themadking oh, amico! ovviamente, usare il tipo esatto sembra migliore di questo mostruoso pezzo di codice sh ... !
Barabas,

337

Ho realizzato alcune estensioni per un facile utilizzo dell'enum. Forse qualcuno può usarlo ...

public static class EnumExtensions
{
    /// <summary>
    /// Gets all items for an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>(this Enum value)
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all items for an enum type.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>() where T : struct
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all combined items from an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <example>
    /// Displays ValueA and ValueB.
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// foreach (var item in dummy.GetAllSelectedItems<EnumExample>())
    /// {
    ///    Console.WriteLine(item);
    /// }
    /// </code>
    /// </example>
    public static IEnumerable<T> GetAllSelectedItems<T>(this Enum value)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);

        foreach (object item in Enum.GetValues(typeof(T)))
        {
            int itemAsInt = Convert.ToInt32(item, CultureInfo.InvariantCulture);

            if (itemAsInt == (valueAsInt & itemAsInt))
            {
                yield return (T)item;
            }
        }
    }

    /// <summary>
    /// Determines whether the enum value contains a specific value.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <param name="request">The request.</param>
    /// <returns>
    ///     <c>true</c> if value contains the specified value; otherwise, <c>false</c>.
    /// </returns>
    /// <example>
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// if (dummy.Contains<EnumExample>(EnumExample.ValueA))
    /// {
    ///     Console.WriteLine("dummy contains EnumExample.ValueA");
    /// }
    /// </code>
    /// </example>
    public static bool Contains<T>(this Enum value, T request)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);
        int requestAsInt = Convert.ToInt32(request, CultureInfo.InvariantCulture);

        if (requestAsInt == (valueAsInt & requestAsInt))
        {
            return true;
        }

        return false;
    }
}

L'enum stesso deve essere decorato con il FlagsAttribute :

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}

13
Una fodera per il primo metodo di estensione; non è più pigro. return Enum.GetValues ​​(typeof (T)). Cast <T> ();
Leyu,

2
In alternativa puoi usare anche OfType: Enum.GetValues ​​(typeof (T)). OfType <T> (). Peccato che non esiste una versione generica di GetValues ​​<T> (), quindi sarebbe ancora più liscia.
jpierson,

3
Forse qualcuno potrebbe mostrare come utilizzare queste estensioni? Il compilatore non mostra i metodi di estensione su EnumExample di enum.
Tomas,

1
qualcuno può aggiungere esempio come utilizzare quelle funzioni?
Ashwini Verma,

3
+1 per il codice riutilizzabile: esempi: salva questi metodi di estensione in una libreria e fai riferimento a [Flags] public enum mytypes {name1, name2}; Elenco <stringa> myTypeNames = mytypes.GetAllItems ();
Krishna il

178

Alcune versioni di .NET framework non supportano Enum.GetValues. Ecco una buona soluzione da Ideas 2.0: Enum.GetValues ​​in Compact Framework :

public Enum[] GetValues(Enum enumeration)
{
    FieldInfo[] fields = enumeration.GetType().GetFields(BindingFlags.Static | BindingFlags.Public);
    Enum[] enumerations = new Enum[fields.Length];

    for (var i = 0; i < fields.Length; i++)
        enumerations[i] = (Enum) fields[i].GetValue(enumeration);

    return enumerations;
}

Come per qualsiasi codice che implica la riflessione , è necessario adottare delle misure per assicurarsi che venga eseguito una sola volta e che i risultati vengano memorizzati nella cache.


18
Perché non usare la parola chiave yield qui invece un'istanza di un elenco?
Eric Mickelsen,

1
o più breve:return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>();
nawfal

7
@nawfal: Linq non è disponibile .Net CF 2.0.
Gabriel GM,

@Ekevoo Come associare i valori di questo enum a un DropDownList in MVC?
Jack,

115

Utilizzare Cast<T>:

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

Ecco qua IEnumerable<Suit>.


1
Questo funziona anche nella fromclausola e nel foreachdichiaratore di intestazione.
Aluan Haddad,

97

Penso che questo sia più efficiente di altri suggerimenti perché GetValues()non viene chiamato ogni volta che hai un ciclo. È anche più conciso. E ottieni un errore di compilazione, non un'eccezione di runtime se Suitnon è un enum.

EnumLoop<Suit>.ForEach((suit) => {
    DoSomethingWith(suit);
});

EnumLoop ha questa definizione completamente generica:

class EnumLoop<Key> where Key : struct, IConvertible {
    static readonly Key[] arr = (Key[])Enum.GetValues(typeof(Key));
    static internal void ForEach(Action<Key> act) {
        for (int i = 0; i < arr.Length; i++) {
            act(arr[i]);
        }
    }
}

6
Attento all'uso di generici come questo. Se si tenta di utilizzare EnumLoopcon un tipo che non è un enum, verrà compilato correttamente, ma verrà generata un'eccezione in fase di esecuzione.
svick

7
Grazie svick. Eccezioni di runtime si verificheranno effettivamente con le altre risposte in questa pagina ... eccetto questa perché ho aggiunto "dove Key: struct, IConvertible" in modo da ottenere un errore di compilazione nella maggior parte dei casi.
James,

3
No, GetValues ​​() viene chiamato solo una volta nella foreach.
Alex Blokha,

4
James, scoraggerei la tua classe perché intelligente è bello da scrivere ma nel codice di produzione che molte persone manterranno e aggiorneranno, intelligente è un lavoro extra. Se fa un grande risparmio o sarà usato molto - quindi i risparmi sono grandi e le persone ne acquisiranno familiarità - ne vale la pena, ma nella maggior parte dei casi rallenta le persone che cercano di leggere e aggiornare il codice e introduce un possibile bug di origine in futuro. Meno codice è meglio :) meno complessità è ancora meglio.
Concedi M

2
@GrantM Perché? Questo codice non è né complesso, ed è incredibilmente breve. Inoltre, scrivere una volta la classe consentirà iterazioni di codice ancora più brevi con l'utilizzo come da suo esempio. Questo è estremamente pulito, se non riesci ad aggiornare quel codice, probabilmente non puoi aggiornare nessuno dei codici delle aziende.
Dispersia,

77

Non entreraiEnum.GetValues() in Silverlight .

Post del blog originale di Einar Ingebrigtsen :

public class EnumHelper
{
    public static T[] GetValues<T>()
    {
        Type enumType = typeof(T);

        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<T> values = new List<T>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add((T)value);
        }

        return values.ToArray();
    }

    public static object[] GetValues(Type enumType)
    {
        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<object> values = new List<object>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add(value);
        }

        return values.ToArray();
    }
}

2
Bella soluzione, ma qualche refactoring sarà migliore! :)
nawfal,

Sto usando .NET framework 4.0 e Silverlight enum.getvalues ​​funziona, il codice che ho usato è ---> enum.GetValues ​​(typeof (enum))
Ananda

2
A partire da C # 7.3 (Visual Studio 2017 ≥ v15.7), si può usarewhere T: Enum
Yahoo Serious

59

La mia soluzione funziona in .NET Compact Framework (3.5) e supporta il controllo del tipo in fase di compilazione :

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();
}
  • Se qualcuno sa come sbarazzarsene T valueType = new T(), sarei felice di vedere una soluzione.

Una chiamata sarebbe simile a questa:

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

2
che ne dici di usare T valueType = default(T)?
Oliver,

Fantastico, non sapevo nemmeno quella parola chiave. Sempre bello imparare qualcosa di nuovo. Grazie! Restituisce sempre un riferimento allo stesso oggetto o crea una nuova istanza ogni volta che viene chiamata l'istruzione predefinita? Finora non ho trovato nulla in rete su questo, ma se crea una nuova istanza ogni volta, sconfigge lo scopo che stavo cercando (avere un one-liner ^^).
Mallox,

1
Questo non creerebbe una nuova istanza per ogni iterazione sull'enumerazione?
Mallox,

1
-1 per "supporta la verifica del tipo in fase di compilazione:". Che tipo di controllo? Questo funzionerebbe per qualsiasi new() T. Inoltre, non è necessario new T()affatto, è possibile selezionare solo i campi statici da solo e fare .GetValue(null). Vedi la risposta di Aubrey.
nawfal,

2
A partire da C # 7.3 (Visual Studio 2017 ≥ v15.7), si può usarewhere T: Enum
Yahoo Serious


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

2
Che enumera una stringa, non dimenticare di riconvertire quelle cose in un valore di enumerazione in modo che l'enumerazione possa essere enumerata.
Ian Boyd,

1
Dalla tua modifica vedo che vuoi effettivamente operare sugli enum stessi, il codice sopra riportato è indirizzato al tuo post originale.
Joshua Drake,

49
foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }

Ho sentito vaghe voci che questo è terribilmente lento. Qualcuno sa? - Orion Edwards, 15 ottobre 2008 alle 1:31 7

Penso che la memorizzazione nella cache dell'array lo accelererebbe notevolmente. Sembra che tu stia ottenendo un nuovo array (attraverso la riflessione) ogni volta. Piuttosto:

Array enums = Enum.GetValues(typeof(Suit));
foreach (Suit suitEnum in enums) 
{
    DoSomething(suitEnum);
}

È almeno un po 'più veloce, ja?


5
Il compilatore dovrebbe occuparsene, però.
Stephan Bijzitter,

@StephanBijzitter Wow, stai leggendo abbastanza in basso su questo :-) Sono d'accordo, il compilatore dovrebbe rendere la mia soluzione non necessaria.
Espiazione limitata il

1
Questo non è necessario Guardando il codice compilato in ILSpy, il compilatore lo fa già sicuramente. Perché questa risposta è stata completamente votata, tanto meno 35 volte?
mhenry1384,

1
È stato votato molto tempo fa. Tanto tempo fa. Scommetto che il compilatore avrebbe risolto anche questo, però. Ma sembra sicuramente più performante, vero? ;-)
Espiazione limitata

32

Tre modi:

  1. Enum.GetValues(type) // Da .NET 1.1, non in Silverlight o .NET Compact Framework
  2. type.GetEnumValues() // Solo su .NET 4 e versioni successive
  3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) // Funziona ovunque

Non sono sicuro del perché sia GetEnumValuesstato introdotto nelle istanze di tipo. Non è molto leggibile per me.


Avere una classe di supporto come Enum<T>è ciò che è più leggibile e memorabile per me:

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

Ora chiami:

Enum<Suit>.GetValues();

// Or
Enum.GetValues(typeof(Suit)); // Pretty consistent style

Si può anche usare una sorta di cache se le prestazioni contano, ma non mi aspetto che questo sia un problema.

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

Questo è un bel riassunto dei metodi. Penso che dovresti fondere la tua altra risposta in questo però. La verità è che l'enum è speciale e il loro ciclo è spesso (di solito) valido quanto l'enumerazione perché sai che i valori non cambieranno mai. IOW, se hai un enum che cambia continuamente, allora hai scelto il costrutto di dati sbagliato per cominciare.
krowe2,

31

Solo combinando le risposte migliori, ho messo insieme un'estensione molto semplice:

public static class EnumExtensions
{
    /// <summary>
    /// Gets all items for an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>(this T value) where T : Enum
    {
        return (T[])Enum.GetValues(typeof (T));
    }
}

È pulito, semplice e, dal commento di @ Jeppe-Stig-Nielsen, veloce.


6
A partire da C # 7.3 (Visual Studio 2017 ≥ v15.7), si può usarewhere T: Enum
Yahoo Serious

24

Esistono due modi per iterare un Enum:

1. var values =  Enum.GetValues(typeof(myenum))
2. var values =  Enum.GetNames(typeof(myenum))

Il primo ti darà valori in forma su un array di ** object** s, e il secondo ti darà valori in forma di un array di ** String** s.

Usalo in un foreachciclo come di seguito:

foreach(var value in values)
{
    // Do operations here
}

2
Forse perché questo è già coperto da molte risposte? Non rendiamo ridondanti le risposte.
nawfal,

@nawfal yes può essere trattato in altre risposte, anche se non concluso bene nella maggior parte di esse.
Kylo Ren,

23

Uso ToString () quindi divido e analizzo l'array spit in flag.

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

17

Non credo che questo sia migliore o addirittura buono. Sto solo affermando l'ennesima soluzione.

Se i valori di enum variano rigorosamente da 0 a n - 1, un'alternativa generica è:

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

Se i valori di enum sono contigui e puoi fornire il primo e l'ultimo elemento dell'enum, allora:

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

Ma ciò non è strettamente enumerato, ma solo in loop. Il secondo metodo è molto più veloce di qualsiasi altro approccio però ...


16

Se hai bisogno di controllo della velocità e del tipo in fase di costruzione e di esecuzione, questo metodo di supporto è meglio dell'utilizzo di LINQ per trasmettere ogni elemento:

public static T[] GetEnumValues<T>() where T : struct, IComparable, IFormattable, IConvertible
{
    if (typeof(T).BaseType != typeof(Enum))
    {
        throw new ArgumentException(string.Format("{0} is not of type System.Enum", typeof(T)));
    }
    return Enum.GetValues(typeof(T)) as T[];
}

E puoi usarlo come di seguito:

static readonly YourEnum[] _values = GetEnumValues<YourEnum>();

Certo che puoi tornare IEnumerable<T>, ma questo non ti compra nulla qui.


3
A partire da C # 7.3 (Visual Studio 2017 ≥ v15.7), si può usarewhere T: Enum
Yahoo Serious

14

Ecco un esempio funzionante di creazione di opzioni di selezione per 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()
      };

10
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}

(L'attuale risposta accettata ha un cast che non credo sia necessario (anche se potrei sbagliarmi).)


10

Questa domanda appare nel capitolo 10 di " C # Step by Step 2013 "

L'autore utilizza un doppio for-loop per scorrere attraverso una coppia di enumeratori (per creare un mazzo completo di carte):

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

In questo caso, Suite Valuesono entrambe le enumerazioni:

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

ed PlayingCardè un oggetto carta con un definito Suite Value:

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

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

funzionerà se i valori in enum non sono sequenziali?
Aamir Masood,


8

Cosa succede se sai che il tipo sarà un enum, ma non sai quale sia il tipo esatto al momento della compilazione?

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

    public static IEnumerable getListOfEnum(Type type)
    {
        MethodInfo getValuesMethod = typeof(EnumHelper).GetMethod("GetValues").MakeGenericMethod(type);
        return (IEnumerable)getValuesMethod.Invoke(null, null);
    }
}

Il metodo getListOfEnumutilizza la riflessione per prendere qualsiasi tipo di enum e restituisce uno IEnumerabledi tutti i valori enum.

Uso:

Type myType = someEnumValue.GetType();

IEnumerable resultEnumerable = getListOfEnum(myType);

foreach (var item in resultEnumerable)
{
    Console.WriteLine(String.Format("Item: {0} Value: {1}",item.ToString(),(int)item));
}

8

Un modo semplice e generico per convertire un enum in qualcosa in cui puoi interagire:

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

E poi:

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

A Dictionarynon è una buona idea: se hai un Enumlike enum E { A = 0, B = 0 }, il valore 0 viene aggiunto 2 volte generando un ArgumentException(non puoi aggiungere lo stesso Keysu Dictionary2 o più volte!).
Massimiliano Kraus,

Perché restituire a Dictionary<,>da un metodo denominato ToList? Inoltre, perché non tornare Dictionary<T, string>?
Aluan Haddad,

8

Aggiungi metodo public static IEnumerable<T> GetValues<T>()alla tua classe, come:

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

Chiama e passa il tuo enum. Ora puoi iterarlo usando foreach:

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

2

enumi tipi sono chiamati "tipi di enumerazione" non perché sono contenitori che "enumerano" i valori (cosa che non sono), ma perché sono definiti enumerando i possibili valori per una variabile di quel tipo.

(In realtà, è un po 'più complicato di così - i tipi di enum sono considerati avere un tipo intero "sottostante", il che significa che ogni valore di enum corrisponde a un valore intero (questo è tipicamente implicito, ma può essere specificato manualmente). C # è stato progettato in un modo in modo da poter riempire qualsiasi numero intero di quel tipo nella variabile enum, anche se non è un valore "nominato".)

Il metodo System.Enum.GetNames può essere utilizzato per recuperare una matrice di stringhe che sono i nomi dei valori enum, come suggerisce il nome.

EDIT: avrebbe dovuto suggerire invece il metodo System.Enum.GetValues . Ops.


2
Sebbene la tua risposta sia corretta di per sé, in realtà non risponde alla domanda originale del PO. Il GetNamesmetodo restituisce, in effetti, una matrice di stringhe, ma l'OP richiede un enumeratore attraverso i valori.
Silviu Preda,

@SilviuPreda: modificato. Avrebbe dovuto essere GetValues ​​anziché GetNames.
Emily Chen,

2

Ho provato molti modi e ho ottenuto il risultato da questo codice:

Per ottenere un elenco di int da un enum, utilizzare quanto segue. Funziona!

List<int> listEnumValues = new List<int>();
YourEnumType[] myEnumMembers = (YourEnumType[])Enum.GetValues(typeof(YourEnumType));
foreach ( YourEnumType enumMember in myEnumMembers)
{
    listEnumValues.Add(enumMember.GetHashCode());
}

1
tanx per edit @ peter-mortensen
reza akhlaghi l'

0

Inoltre puoi associare direttamente ai membri statici pubblici dell'enum usando reflection:

typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static)
    .ToList().ForEach(x => DoSomething(x.Name));

0

Se hai:

enum Suit
{
   Spades,
   Hearts,
   Clubs,
   Diamonds
}

Questo:

foreach (var e in Enum.GetValues(typeof(Suit)))
{
    Console.WriteLine(e.ToString() + " = " + (int)e);
}

Uscita:

Spades = 0
Hearts = 1
Clubs = 2
Diamonds = 3

0

LINQModo generico :

    public static Dictionary<int, string> ToList<T>() where T : struct =>
        ((IEnumerable<T>)Enum.GetValues(typeof(T))).ToDictionary(value => Convert.ToInt32(value), value => value.ToString());

Uso:

        var enums = ToList<Enum>();
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.