c# c++ imprimir - ¿Cómo enumero una enumeración en C #?





13 Answers

Me parece que realmente desea 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, aumentar el valor no es una buena manera de enumerar los valores de una enumeración. Deberías hacer esto en su lugar.

Yo usaría 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());
    }
}
typedef ejemplo para

¿Cómo se puede enumerar una enum en 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 de compilación:

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

Falla en la palabra clave Suit , la segunda.




Algunas versiones de .NET framework no admiten Enum.GetValues . Aquí hay una buena solución de Ideas 2.0: Enum.GetValues ​​en Compact Framework :

public List<Enum> GetValues(Enum enumeration)
{
   List<Enum> enumerations = new List<Enum>();
   foreach (FieldInfo fieldInfo in enumeration.GetType().GetFields(
         BindingFlags.Static | BindingFlags.Public))
   {
      enumerations.Add((Enum)fieldInfo.GetValue(enumeration));
   }
   return enumerations;
}

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




¿Por qué nadie usa Cast<T> ?

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

Ahí tienes IEnumerable<Suit> .




Solo para agregar mi solución, que funciona en un marco compacto (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 T valueType = new T() , estaré encantado de ver una solución.

Una llamada se vería así:

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



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



Tres maneras:

1. Enum.GetValues(type) //since .NET 1.1, not in silverlight or compact framewok
2. type.GetEnumValues() //only on .NET 4 and above
3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) //works everywhere

No estoy seguro de por qué se introdujo GetEnumValues en la instancia de tipo, no es muy legible para mí.

Tener una clase de ayuda como Enum<T> es lo 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 una especie 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)));
    }
}



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



No tengo la opinión de que esto es mejor, o incluso bueno, simplemente declarando otra solución.

Si los valores de enumeración van estrictamente de 0 a n - 1, una alternativa genérica:

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. El segundo método es mucho más rápido que cualquier otro enfoque, aunque ...




Aquí hay un ejemplo práctico de cómo 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()
      };



Esta pregunta aparece en el Capítulo 10 de " C # Step by Step 2013 "

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

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 Suit y Value definidos:

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

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



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



Agregue el 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 enum, ahora puedes recorrerla usando foreach

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



enum tipos de enum se denominan "tipos de enumeración" no porque sean contenedores que "enumeren" valores (que no son), sino porque se definen al enumerar 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 manera que pueda incluir cualquier 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 el nombre.

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






Related