Cómo enumerar una enumeración

3768

¿Cómo se puede enumerar un enumen C #?

Por ejemplo, el siguiente código no se compila:

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

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

Y da el siguiente error en tiempo de compilación:

'Traje' es un 'tipo' pero se usa como una 'variable'

Falla en la Suitpalabra clave, la segunda.

Ian Boyd
fuente
17
Ver también ... stackoverflow.com/questions/972307/…
SteveC
2
Es posible que desee ver los entresijos de las enumeraciones de C # , que discute esto, así como otros datos útiles de enumeración
ChaseMedallion

Respuestas:

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

Nota : La conversión a (Suit[])no es estrictamente necesaria, pero hace que el código sea 0.5 ns más rápido .

jop
fuente
97
Esto no funciona si tiene valores duplicados en la lista del enumerador.
Jessy
10
Solo quiero señalar que esto, desafortunadamente no funcionará en Silverlight, ya que la biblioteca Silverlight no comprende enum.GetValues. Tienes que usar la reflexión en este caso.
Giacomo Tagliabue
146
@Jessy esto hace el trabajo en caso de situaciones como duplicados enum E {A = 0, B = 0}. Enum.GetValuesda como resultado la devolución de dos valores, aunque son los mismos. E.A == E.Bes cierto, entonces no hay distinción. Si desea nombres individuales, entonces debe buscar Enum.GetNames.
nawfal
13
Luego, si tiene duplicados / sinónimos en su enumeración y desea el otro comportamiento, puede usar la Distinctextensión de Linq (desde .NET 3.5), entonces foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }.
Jeppe Stig Nielsen
42
Cometí el error de intentar usar varpara el tipo. El compilador convertirá la variable en un Objectlugar de la enumeración. Listar el tipo de enumeración explícitamente.
jpmc26
695

Me parece que realmente quieres imprimir los nombres de cada enumeración, en lugar de los valores. En cuyo caso Enum.GetNames()parece ser el enfoque correcto.

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

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

Por cierto, incrementar el valor no es una buena forma de enumerar los valores de una enumeración. Deberías hacer esto en su lugar.

Yo usaría en su Enum.GetValues(typeof(Suit))lugar.

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

public void PrintAllSuits()
{
    foreach (var suit in Enum.GetValues(typeof(Suits)))
    {
        System.Console.WriteLine(suit.ToString());
    }
}
Hackeado
fuente
2
VB Sintaxis aquí: enlace
AndruWitta
Tomé su versión con unos pequeños cambios que se derivan de mi lado: Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray(). En ese caso, puedo iterar una matriz de Suitselementos de enumeración, no cadenas.
Barabas
@Barabas, ¿por qué no simplemente hacerlo Suits suit in Enum.GetValues(typeof(Suits))?
themadking
@ themadking oh, hombre! por supuesto, ¡usar el tipo exacto se ve mejor que este monstruoso pedazo de sh ... código!
Barabas
337

Hice algunas extensiones para facilitar el uso de la enumeración. Quizás alguien pueda 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;
    }
}

La enumeración en sí debe estar decorada con el atributo FlagsAttribute :

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}
Beto
fuente
13
Una línea para el primer método de extensión; No es más vago. return Enum.GetValues ​​(typeof (T)). Cast <T> ();
Leyu
2
Alternativamente, también puede usar OfType: Enum.GetValues ​​(typeof (T)). OfType <T> (). Es una pena que no haya una versión genérica de GetValues ​​<T> (), entonces sería aún más elegante.
jpierson
3
¿Quizás alguien podría mostrar cómo usar estas extensiones? El compilador no muestra métodos de extensión en enum EnumExample.
Tomás
1
¿Alguien puede agregar un ejemplo de cómo utilizar esas funciones?
Ashwini Verma
3
+1 para código reutilizable: ejemplos: guarde estos métodos de extensión en una biblioteca y haga referencia a él [Banderas] public enum mytypes {name1, name2}; List <string> myTypeNames = mytypes.GetAllItems ();
Krishna
178

Algunas versiones de .NET Framework no son compatibles Enum.GetValues. Aquí hay una buena solución de Ideas 2.0: Enum.GetValues ​​en 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;
}

Al igual que con cualquier código que implique reflexión , debe tomar medidas para asegurarse de que se ejecute solo una vez y que los resultados se almacenen en caché.

Ekevoo
fuente
18
¿Por qué no usar la palabra clave de rendimiento aquí en lugar de crear una instancia de una lista?
Eric Mickelsen
1
o más corto:return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>();
nawfal
77
@nawfal: Linq no está disponible .Net CF 2.0.
Gabriel GM
@Ekevoo ¿Cómo vincular estos valores de enumeración a una DropDownList en MVC?
Jack
115

Uso Cast<T>:

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

Hay que ir, IEnumerable<Suit>.

sircodesalot
fuente
1
Esto también funciona en la fromcláusula y el foreachdeclarador de encabezado.
Aluan Haddad
97

Creo que esto es más eficiente que otras sugerencias porque GetValues()no se llama cada vez que tienes un bucle. También es más conciso. Y obtiene un error en tiempo de compilación, no una excepción de tiempo de ejecución si Suitno es un enum.

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

EnumLoop tiene esta definición completamente genérica:

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]);
        }
    }
}
James
fuente
66
Cuidado con el uso de genéricos como este. Si intenta utilizar EnumLoopalgún tipo que no sea una enumeración, se compilará bien, pero arrojará una excepción en tiempo de ejecución.
svick
77
Gracias svick. Las excepciones de tiempo de ejecución realmente ocurrirán con las otras respuestas en esta página ... excepto esta porque he agregado "where Key: struct, IConvertible" para que obtenga un error de tiempo de compilación en la mayoría de los casos.
James
3
No, GetValues ​​() se llama solo una vez en el foreach.
Alex Blokha
44
James, desanimaría a tu clase porque inteligente es agradable de escribir, pero en el código de producción que mucha gente mantendrá y actualizará, inteligente es un trabajo extra. Si ahorra mucho o se usará mucho, por lo que el ahorro es grande y la gente se familiarizará con él, vale la pena, pero en la mayoría de los casos ralentiza a las personas que intentan leer y actualizar el código e introduce un posible errores de origen en el futuro. Menos código es mejor :) menos complejidad es aún mejor.
Grant M
2
@GrantM ¿Por qué? Este código no es complejo y es increíblemente corto. Además de eso, escribir la clase una vez permitirá iteraciones de código aún más cortas con el uso, según su ejemplo. Esto es extremadamente limpio, si no puede actualizar ese código, probablemente no pueda actualizar ninguno de los códigos de las compañías.
Dispersia
77

No entrarásEnum.GetValues() en Silverlight .

Publicación de blog original de 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();
    }
}
Aubrey Taylor
fuente
2
Buena solución, ¡pero un poco de refactorización será mejor! :)
nawfal
Estoy usando .NET framework 4.0 y silverlight enum.getvalues ​​work, el código que usé es ---> enum.GetValues ​​(typeof (enum))
Ananda
2
Comenzando con C # 7.3 (Visual Studio 2017 ≥ v15.7), uno puede usar where T: Enum
Yahoo Serious
59

Mi solución funciona en .NET Compact Framework (3.5) y admite la verificación de tipos en tiempo de compilación :

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 alguien sabe cómo deshacerse de él T valueType = new T(), me encantaría ver una solución.

Una llamada se vería así:

List<MyEnum> result = Utils.GetEnumValues<MyEnum>();
Mallox
fuente
2
¿Qué hay de usar T valueType = default(T)?
Oliver
Genial, ni siquiera sabía esa palabra clave. Siempre es bueno aprender algo nuevo. ¡Gracias! ¿Siempre devuelve una referencia al mismo objeto, o crea una nueva instancia cada vez que se llama a la instrucción predeterminada? Hasta ahora no he encontrado nada en la red sobre esto, pero si crea una nueva instancia cada vez, de alguna manera frustra el propósito que estaba buscando (tener una frase ^^).
Mallox
1
¿No crearía esto una nueva instancia para cada iteración sobre la enumeración?
Mallox
1
-1 para "admite la verificación de tipos en tiempo de compilación:". ¿Qué tipo de comprobación? Esto funcionaría para cualquiera new() T. Además, no necesita new T()nada, puede seleccionar solo los campos estáticos y hacer .GetValue(null). Ver la respuesta de Aubrey.
nawfal
2
Comenzando con C # 7.3 (Visual Studio 2017 ≥ v15.7), se puede usarwhere T: Enum
Yahoo Serious
52

Creo que puedes usar

Enum.GetNames(Suit)
Tom Carr
fuente
66
Enum.GetValues ​​(trajes)
Ian Boyd
50
public void PrintAllSuits()
{
    foreach(string suit in Enum.GetNames(typeof(Suits)))
    {
        Console.WriteLine(suit);
    }
}
Joshua Drake
fuente
2
Eso enumera una cadena, no olvide convertir esas cosas nuevamente en un valor de enumeración para que la enumeración pueda enumerarse.
Ian Boyd
1
Veo por su edición que realmente desea operar en las enumeraciones, el código anterior se dirigió a su publicación original.
Joshua Drake
49
foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }

He escuchado vagos rumores de que esto es terriblemente lento. ¿Nadie sabe? - Orion Edwards Oct 15 '08 a las 1:31 7

Creo que el almacenamiento en caché de la matriz lo aceleraría considerablemente. Parece que está obteniendo una nueva matriz (a través de la reflexión) cada vez. Más bien:

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

Eso es al menos un poco más rápido, ¿ja?

Expiación limitada
fuente
55
Sin embargo, el compilador debería encargarse de esto.
Stephan Bijzitter
@StephanBijzitter Wow, estás leyendo bastante lejos sobre esto :-) Estoy de acuerdo, el compilador debería hacer que mi solución sea innecesaria.
Expiación limitada
1
Esto no es necesario. Mirando el código compilado en ILSpy, el compilador definitivamente ya lo hace. ¿Por qué esta respuesta está votada, mucho menos 35 veces?
mhenry1384
1
Fue votado hace mucho tiempo. Hace mucho tiempo. Sin embargo, apostaría a que el compilador también habría resuelto esto en ese entonces. Pero seguro que se ve más eficiente, ¿no? ;-)
Expiación limitada
32

Tres maneras:

  1. Enum.GetValues(type) // Desde .NET 1.1, no en Silverlight o .NET Compact Framework
  2. type.GetEnumValues() // Solo en .NET 4 y superior
  3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) // Funciona en todas partes

No estoy seguro de por qué GetEnumValuesse introdujo en instancias de tipo. No es muy legible para mí.


Tener una clase auxiliar Enum<T>es lo que es más legible y memorable para mí:

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

Ahora llamas:

Enum<Suit>.GetValues();

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

También se puede usar algún tipo de almacenamiento en caché si el rendimiento es importante, pero no espero que esto sea un problema en absoluto.

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)));
    }
}
nawfal
fuente
Este es un buen resumen de los métodos. Sin embargo, creo que deberías combinar tu otra respuesta en esto. La verdad es que las enumeraciones son especiales y recorrerlas a menudo es (generalmente) tan válido como la enumeración porque sabes que los valores nunca cambiarán. IOW, si tienes una enumeración que cambia todo el tiempo, entonces has elegido la construcción de datos incorrecta para empezar.
krowe2
31

Simplemente combinando las respuestas principales, creé una extensión muy simple:

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

Es limpio, simple y, según el comentario de @ Jeppe-Stig-Nielsen, rápido.

Lado oscuro
fuente
66
Comenzando con C # 7.3 (Visual Studio 2017 ≥ v15.7), se puede usarwhere T: Enum
Yahoo Serious
24

Hay dos formas de iterar un Enum:

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

El primero le dará valores en forma en una matriz de ** object** s, y el segundo le dará valores en forma de una matriz de **String ** s.

Úselo en un foreachbucle como a continuación:

foreach(var value in values)
{
    // Do operations here
}
Kylo Ren
fuente
2
Tal vez porque esto ya está cubierto en muchas respuestas? No hagamos respuestas redundantes.
nawfal
@nawfal yes puede estar cubierto en otras respuestas, aunque no está bien concluido en la mayoría de ellas.
Kylo Ren
23

Uso ToString () y luego divido y analizo la matriz de spit en banderas.

[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);
}
Mickey Perlstein
fuente
17

No creo que esto sea mejor, ni siquiera bueno. Solo estoy diciendo otra solución más.

Si los valores de enumeración varían estrictamente de 0 a n - 1, una alternativa genérica es:

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

Si los valores de enumeración son contiguos y puede proporcionar el primer y último elemento de la enumeración, entonces:

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

Pero eso no es estrictamente enumerar, solo hacer un bucle. Sin embargo, el segundo método es mucho más rápido que cualquier otro enfoque ...

nawfal
fuente
16

Si necesita comprobación de velocidad y tipo en tiempo de compilación y ejecución, este método auxiliar es mejor que usar LINQ para convertir cada 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[];
}

Y puedes usarlo como a continuación:

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

Por supuesto que puedes regresar IEnumerable<T>, pero eso no te compra nada aquí.

dmihailescu
fuente
3
Comenzando con C # 7.3 (Visual Studio 2017 ≥ v15.7), se puede usarwhere T: Enum
Yahoo Serious
14

Aquí hay un ejemplo de trabajo para crear opciones de selección para 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()
      };
jhilden
fuente
10
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}

(La respuesta aceptada actual tiene un reparto que no creo que sea necesario (aunque puedo estar equivocado)).

quemaduras mate
fuente
10

Esta pregunta aparece en el Capítulo 10 de " C # paso a paso 2013 "

El autor utiliza un doble for-loop para iterar a través de un par de enumeradores (para crear una baraja completa de cartas):

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

En este caso, Suity Valueson ambas enumeraciones:

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

y PlayingCardes un objeto de tarjeta con un definido Suity Value:

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

    public PlayingCard(Suit s, Value v)
    {
        this.suit = s;
        this.value = v;
    }
}
Ross Gatih
fuente
¿funcionará esto si los valores en enum no son secuenciales?
Aamir Masood
10

Sé que es un poco desordenado, pero si eres fanático de las frases sencillas, aquí hay una:

((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));
anar khalilov
fuente
2
¿ Eso es lisp ?
Mikael Dúi Bolinder
8

¿Qué enumsucede si sabe que el tipo será un , pero no sabe cuál es el tipo exacto en tiempo de compilación?

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

El método getListOfEnumusa la reflexión para tomar cualquier tipo de enumeración y devuelve uno IEnumerablede todos los valores de enumeración.

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));
}
Slappywag
fuente
8

Una forma simple y genérica de convertir una enumeración en algo con lo que pueda interactuar:

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

Y entonces:

var enums = EnumHelper.ToList<MyEnum>();
Gabriel
fuente
A Dictionaryno es una buena idea: si tienes un me Enumgusta enum E { A = 0, B = 0 }, el valor 0 se agrega 2 veces generando un ArgumentException(¡no puedes agregar lo mismo Keyen Dictionary2 o más veces!).
Massimiliano Kraus
¿Por qué devolver un Dictionary<,>de un método llamado ToList? Además, ¿por qué no volver Dictionary<T, string>?
Aluan Haddad
8

Agregue un método public static IEnumerable<T> GetValues<T>()a su clase, como:

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

Llama y pasa tu enumeración. Ahora puedes recorrerlo usando foreach:

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

enumlos tipos se denominan "tipos de enumeración" no porque sean contenedores que "enumeren" valores (que no lo son), sino porque se definen enumerando los valores posibles para una variable de ese tipo.

(En realidad, eso es un poco más complicado que eso: se considera que los tipos de enumeración tienen un tipo entero "subyacente", lo que significa que cada valor de enumeración corresponde a un valor entero (esto generalmente es implícito, pero puede especificarse manualmente). C # fue diseñado en cierto modo para que puedas rellenar cualquier número entero de ese tipo en la variable enum, incluso si no es un valor "con nombre").

El método System.Enum.GetNames se puede usar para recuperar una matriz de cadenas que son los nombres de los valores de enumeración, como sugiere su nombre.

EDITAR: Debería haber sugerido el método System.Enum.GetValues ​​en su lugar. Ups

Emily Chen
fuente
2
Aunque su respuesta es correcta en sí misma, en realidad no aborda la pregunta original del OP. El GetNamesmétodo devuelve, de hecho, una matriz de cadenas, pero el OP requiere un enumerador a través de los valores.
Silviu Preda
@SilviuPreda: Editado. Debería haber sido GetValues ​​en lugar de GetNames.
Emily Chen
2

Lo intenté de muchas maneras y obtuve el resultado de este código:

Para obtener una lista de int de una enumeración, use lo siguiente. ¡Funciona!

List<int> listEnumValues = new List<int>();
YourEnumType[] myEnumMembers = (YourEnumType[])Enum.GetValues(typeof(YourEnumType));
foreach ( YourEnumType enumMember in myEnumMembers)
{
    listEnumValues.Add(enumMember.GetHashCode());
}
reza akhlaghi
fuente
1
tanx para editar @ peter-mortensen
reza akhlaghi
0

También puede vincularse a los miembros estáticos públicos de la enumeración directamente mediante el uso de la reflexión:

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

Si usted tiene:

enum Suit
{
   Spades,
   Hearts,
   Clubs,
   Diamonds
}

Esta:

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

Saldrá:

Spades = 0
Hearts = 1
Clubs = 2
Diamonds = 3
rlv-dan
fuente
0

Manera genérica de LINQ :

    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>();
Erçin Dedeoğlu
fuente