Cómo enumerar una enumeración

¿Cómo puedes enumerar un enum 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 el Suit palabra clave, la segunda.

preguntado el 19 de septiembre de 08 a las 18:09

Es posible que desee ver los entresijos de las enumeraciones de C #, que analiza esto, así como otros datos útiles de enumeración:

30 Respuestas

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

Nota:: El elenco de (Suit[]) no es estrictamente necesario, pero hace que el código sea 0.5 ns más rápido.

Respondido el 09 de diciembre de 19 a las 22:12

Esto no funciona si tiene valores duplicados en la lista de enumeradores. - Jessy

Solo quiero señalar que esto, desafortunadamente, no funcionará en silverlight, ya que la biblioteca de silverlight no incluye enum.GetValues. Tienes que usar la reflexión en este caso. - Giacomo Tagliabue

@Jessy esto trabajar en caso de situaciones duplicadas como enum E {A = 0, B = 0}. Enum.GetValues da como resultado que se devuelvan dos valores, aunque son iguales. E.A == E.B es cierto, por lo que no hay distinción. Si desea nombres individuales, debe buscar Enum.GetNames. - nawfal

Luego, si tiene duplicados / sinónimos en su enumeración y desea el otro comportamiento, puede usar Linq's Distinct extensión (desde .NET 3.5), entonces foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }. - Jeppe Stig Nielsen

Cometí el error de intentar usar var para el tipo. El compilador convertirá la variable en un Object en lugar de la enumeración. Enumere el tipo de enumeración explícitamente. - jpmc26

Me parece que realmente desea imprimir los nombres de cada enumeración, en lugar de los valores. En ese 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 Enum.GetValues(typeof(Suit)) preferiblemente.

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

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

Respondido 10 Feb 14, 18:02

Sintaxis de VB aquí: aquí - Andru Witta

Tomé su versión con unos pequeños cambios siguientes de mi lado: Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray(). En ese caso, puedo iterar una matriz de Suits elementos de enumeración, no cadenas. - Barabas

@Barabas, ¿por qué no hacerlo? Suits suit in Enum.GetValues(typeof(Suits)) ? - el loco

@themadking ¡oh, hombre! Por supuesto, usar el tipo exacto se ve mejor que esta monstruosa pieza de sh ... ¡código! - Barabas

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 la Banderas Atributo:

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

Respondido el 09 de diciembre de 19 a las 22:12

Un trazador de líneas para el primer método de extensión; ya no es perezoso. return Enum.GetValues ​​(typeof (T)). Cast (); - Leyu

Alternativamente, también puede usar OfType: Enum.GetValues ​​(typeof (T)). OfType (). Es una lástima que no haya una versión genérica de GetValues () entonces sería aún más hábil. - jpierson

¿Quizás alguien podría mostrar cómo usar estas extensiones? El compilador no muestra métodos de extensión en la enumeración EnumExample. - Tomas

+1 para código reutilizable: ejemplos: guarde estos métodos de extensión en una biblioteca y haga referencia a ellos [Flags] public enum mytypes {name1, name2}; Lista myTypeNames = mytypes.GetAllItems (); - Krishna

A partir de C # 7.3 (Visual Studio 2017 ≥ v15.7), se puede usar where T: Enum - Yahoo Serious

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

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

respondido 08 mar '19, 04:03

¿Por qué no utilizar la palabra clave de rendimiento aquí en lugar de crear una instancia de una lista? - eric mickelsen

o más corto: return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>(); - nawfal

@nawfal: Linq no está disponible .Net CF 2.0. - gabriel

Utiliza Cast<T>:

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

Hay que ir IEnumerable<Suit>.

Respondido el 09 de diciembre de 19 a las 22:12

Esto también funciona en el from cláusula y la foreach declarador de encabezado. - Aluan Haddad

Este parece ser el enfoque más limpio. - Jessica

Creo que esto es más eficaz que otras sugerencias porque GetValues() no se llama cada vez que tiene un bucle. También es más conciso. Y obtiene un error en tiempo de compilación, no una excepción en tiempo de ejecución si Suit no 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]);
        }
    }
}

Respondido el 09 de diciembre de 19 a las 22:12

Tenga cuidado con el uso de genéricos como este. Si intentas usar EnumLoop con algún tipo que no sea una enumeración, se compilará bien, pero lanzará una excepción en tiempo de ejecución. - svick

Gracias svick. En realidad, las excepciones en tiempo de ejecución ocurrirán con las otras respuestas en esta página ... excepto esta porque he agregado "donde Key: struct, IConvertible" para que obtenga un error de tiempo de compilación en la mayoría de los casos. - James

No, se llama a GetValues ​​() solo una vez en foreach. - Alex Bloka

James, desanimaría a tu clase porque inteligente es bueno de escribir, pero en el código de producción que mucha gente mantendrá y actualizará, inteligente es trabajo extra. Si genera un gran ahorro o se usará mucho, para que el ahorro sea grande y la gente se familiarice 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 una posible errores de origen en el futuro. Menos código es mejor :) menos complejidad es aún mejor. - conceder m

@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 empresas. - Dispersia

No obtendrás Enum.GetValues() in Silverlight.

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

Respondido el 09 de diciembre de 19 a las 22:12

Buena solución, ¡pero algo de refactorización será mejor! :) - nawfal

Estoy usando .NET framework 4.0 y silverlight enum.getvalues ​​funcionan, el código que usé es ---> enum.GetValues ​​(typeof (enum)) - Ananda

A partir de C # 7.3 (Visual Studio 2017 ≥ v15.7), se puede usar where T: Enum - Yahoo Serious

Mi solución funciona en Marco compacto .NET (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 la T valueType = new T(), Estaría feliz de ver una solución.

Una llamada se vería así:

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

Respondido el 09 de diciembre de 19 a las 22:12

que hay de usar T valueType = default(T)? - Oliver

Genial, ni siquiera conocía esa palabra clave. Siempre es bueno aprender algo nuevo. ¡Gracias! ¿Devuelve siempre una referencia al mismo objeto o crea una nueva instancia cada vez que se llama a la declaración predeterminada? No he encontrado nada en la red sobre esto hasta ahora, pero si crea una nueva instancia cada vez, frustra el propósito que estaba buscando (tener una sola línea ^^). - Mallox

¿No crearía esto una nueva instancia para cada iteración sobre la enumeración? - Mallox

-1 para "admite la verificación de tipos en el momento de la compilación:". ¿Qué tipo de verificación? Esto funcionaría para cualquier new() T. Además, no necesitas new T() en absoluto, puede seleccionar solo los campos estáticos y hacer .GetValue(null). Vea la respuesta de Aubrey. - nawfal

A partir de C # 7.3 (Visual Studio 2017 ≥ v15.7), se puede usar where T: Enum - Yahoo Serious

Creo que puedes usar

Enum.GetNames(Suit)

Respondido 25 Jul 11, 08:07

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

Respondido el 09 de enero de 17 a las 20:01

Eso enumera una cadena, no olvide convertir esas cosas de nuevo en un valor de enumeración para que la enumeración se pueda enumerar. - Ian Boyd

Veo en su edición que realmente desea operar en las enumeraciones mismas, el código anterior se dirigió a su publicación original. - joshua drake

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

He oído rumores vagos de que esto es terriblemente lento. ¿Nadie sabe? - Orion Edwards 15 de octubre de 08 a las 1:31 7

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

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

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

Respondido 06 Oct 17, 08:10

Sin embargo, el compilador debería encargarse de esto. - Stephan Bijzitter

@StephanBijzitter Wow, estás leyendo bastante hacia abajo en este :-) Estoy de acuerdo, el compilador debería hacer que mi solución sea innecesaria. - lmat - Reincorporar a Monica

Esto no es necesario. Mirando el código compilado en ILSpy, el compilador definitivamente ya lo hace. ¿Por qué esta respuesta es votada a favor, mucho menos 35 veces? - mhenry1384

Fue votado a favor 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 miradas más eficiente, ¿no? ;-) - lmat - Reincorporar a Monica

Con solo combinar las respuestas principales, reuní 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.

Respondido el 09 de diciembre de 19 a las 22:12

A partir de C # 7.3 (Visual Studio 2017 ≥ v15.7), se puede usar where T: Enum - Yahoo Serious

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 por qué GetEnumValues se introdujo en instancias de tipo. No es muy legible para mí.


Tener una clase de ayuda como 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 importa, 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)));
    }
}

Respondido el 09 de diciembre de 19 a las 22:12

Este es un buen resumen de métodos. Sin embargo, creo que deberías combinar tu otra respuesta en esta. La verdad es que las enumeraciones son especiales y recorrerlas a menudo (generalmente) es tan válido como la enumeración porque sabe que los valores nunca cambiarán. IOW, si tiene una enumeración que cambia todo el tiempo, entonces ha elegido la construcción de datos incorrecta para empezar. - krowe2

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 foreach bucle de la siguiente manera:

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

Respondido el 09 de diciembre de 19 a las 23:12

¿Quizás porque esto ya está cubierto en muchas respuestas? No hagamos que las respuestas sean redundantes. - nawfal

@nawfal yes puede estar cubierto en otras respuestas, aunque no se concluye bien en la mayoría de ellas. - Kylo Ren

Utilizo ToString (), luego divido y analizo la matriz de escupir 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);
}

respondido 18 nov., 15:15

No creo que esto sea mejor, ni siquiera bueno. Solo estoy indicando otra solución.

Si los valores de enumeración van 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 una enumeración estricta, solo un bucle. Sin embargo, el segundo método es mucho más rápido que cualquier otro enfoque ...

Respondido el 20 de junio de 20 a las 10:06

Si necesita verificar la velocidad y el tipo en el 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 se muestra a continuación:

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

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

Respondido el 17 de enero de 16 a las 12:01

A partir de C # 7.3 (Visual Studio 2017 ≥ v15.7), se puede usar where T: Enum - Yahoo Serious

A continuación se muestra un ejemplo práctico de creación de 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()
      };

Respondido el 09 de diciembre de 19 a las 22:12

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

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

Respondido el 17 de enero de 16 a las 12:01

Agregar método public static IEnumerable<T> GetValues<T>() a tu clase, como:

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

Llame y pase su enumeración. Ahora puedes recorrerlo usando foreach:

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

Respondido el 09 de diciembre de 19 a las 23:12

Agregaría "donde T: struct, Enum" para restringir el método a enumeraciones. Como este IEnumerable público estático ObtenerValores () donde T: struct, Enum => Enum.GetValues ​​(typeof (T)). Cast (); - Desmond

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

El autor usa un bucle for doble 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, Suit y Value son ambas enumeraciones:

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

y PlayingCard es un objeto de tarjeta con un definido Suit y Value:

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

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

Respondido el 13 de enero de 17 a las 07:01

¿Funcionará esto si los valores en enum no son secuenciales? - Aamir Masood

Sé que es un poco complicado, pero si eres fanático de las frases ingeniosas, aquí tienes una:

((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));

Respondido el 09 de diciembre de 19 a las 23:12

Una forma simple y genérica de convertir una enumeración en algo con lo que puede 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>();

Respondido 25 Oct 16, 15:10

A Dictionary no es una buena idea: si tiene un Enum como enum E { A = 0, B = 0 }, el valor 0 se suma 2 veces generando un ArgumentException (no puedes agregar lo mismo Key en un Dictionary ¡2 o más veces!). - massimiliano kraus

¿Por qué devolver un Dictionary<,> de un método llamado ToList? También por qué no volver Dictionary<T, string>? - Aluan Haddad

¿Qué pasa si sabes que el tipo será un enum, pero ¿no sabe cuál es el tipo exacto en el momento de la 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 getListOfEnum usa la reflexión para tomar cualquier tipo de enumeración y devuelve un IEnumerable de 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));
}

Respondido 01 Oct 15, 11:10

Nueva solución .NET 5:

.NET 5 ha introducido un una versión genérica para el GetValues método:

Suit[] suitValues = Enum.GetValues<Suit>();

Uso en un bucle foreach:

foreach (Suit suit in Enum.GetValues<Suit>())
{

}

que ahora es, con mucho, la solución más conveniente.

Respondido el 02 de diciembre de 20 a las 06:12

enum Los tipos se denominan "tipos de enumeración" no porque sean contenedores que "enumeran" valores (que no lo son), sino porque están definidos por 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 suele ser implícito, pero se puede especificar manualmente). C # fue diseñado de una manera para que puedas rellenar cualquier entero de ese tipo en la variable enum, incluso si no es un valor "nombrado").

El sistema 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 el nombre.

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

Respondido el 16 de enero de 18 a las 20:01

Aunque su respuesta es correcta en sí misma, realmente no aborda la pregunta original del OP. La GetNames El método devuelve, de hecho, una matriz de cadenas, pero el OP requiere un enumerador a través de los valores. - Silvi Preda

@SilviuPreda: Editado. Debería haber sido GetValues ​​en lugar de GetNames. - emily chen

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

Respondido el 26 de enero de 21 a las 13:01

Cuando tienes un poco enum como este

enum DemoFlags
{
    DemoFlag = 1,
    OtherFlag = 2,
    TestFlag = 4,
    LastFlag = 8,
}

Con esta cesión

DemoFlags demoFlags = DemoFlags.DemoFlag | DemoFlags.TestFlag;

y necesito un resultado como este

"DemoFlag | TestFlag"

este método ayuda:

public static string ConvertToEnumString<T>(T enumToConvert, string separator = " | ") where T : Enum
{
    StringBuilder convertedEnums = new StringBuilder();

    foreach (T enumValue in Enum.GetValues(typeof(T)))
    {
        if (enumToConvert.HasFlag(enumValue)) convertedEnums.Append($"{ enumValue }{separator}");
    }

    if (convertedEnums.Length > 0) convertedEnums.Length -= separator.Length;

    return convertedEnums.ToString();
}

Respondido 08 Feb 21, 22:02

También puede enlazar a los miembros estáticos públicos de la enumeración directamente usando la reflexión:

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

Respondido el 09 de enero de 17 a las 23:01

Si 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

respondido 21 nov., 19:11

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.