valor Como faço para enumerar um enum em c#?




pegar valor enum c# (21)

Como você pode enumerar um enum em c #?

Por exemplo, o código a seguir não compila:

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

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

E dá o seguinte erro de tempo de compilação:

'Suit' é um 'tipo' mas é usado como uma 'variável'

Ele falha na palavra-chave Suit , o segundo.


aqui está um exemplo de trabalho de criação de opções de seleção para um 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()
      };

Que diabos eu vou jogar meus dois centavos, apenas combinando as melhores respostas através de uma extensão muito simples

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)
    {
        return (T[])Enum.GetValues(typeof (T));
    }
}

Limpar simples e por @ Jeppe-Stig-Nielsen s comentário rápido.


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

Eu uso ToString (), em seguida, dividir e analisar a matriz de cuspir em bandeiras.

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

Você não receberá Enum.GetValues() no Silverlight.

Postagem original no blog por 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();
    }
}

Parece-me que você realmente quer imprimir os nomes de cada enum, em vez dos valores. Nesse caso, Enum.GetNames() parece ser a abordagem correta.

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

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

By the way, incrementar o valor não é uma boa maneira de enumerar os valores de um enum. Você deveria fazer isso em vez disso.

Eu usaria Enum.GetValues(typeof(Suit)) vez disso.

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

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

Três caminhos:

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

Não tenho certeza por que foi GetEnumValues introduzido na instância de tipo, não é muito legível para mim.

Ter uma classe auxiliar como Enum<T> é o que é mais legível e memorável para mim:

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

Agora você chama:

Enum<Suit>.GetValues();
//or
Enum.GetValues(typeof(Suit)); //pretty consistent style

Também é possível usar o tipo de armazenamento em cache se o desempenho for importante, mas não espero que isso seja um 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)));
    }
}

Existem duas maneiras de iterar um Enum :

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

O primeiro lhe dará valores em forma em um array de object , e o segundo lhe dará valores em forma de array de String .

Use-o no laço foreach como abaixo:

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

Adicionar método public static IEnumerable<T> GetValues<T>() à sua classe, como

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

ligue e passe seu enum, agora você pode iterar através dele usando foreach

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

Eu fiz algumas extensões para facilitar o uso do enum, talvez alguém possa usá-lo ...

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

O enum em si deve ser decorado com o FlagsAttribute

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

Algumas versões do .NET framework não suportam Enum.GetValues . Aqui está uma boa solução alternativa do Ideas 2.0: Enum.GetValues ​​no 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;
}

Como acontece com qualquer código que envolva reflection , você deve tomar medidas para garantir que seja executado apenas uma vez e os resultados sejam armazenados em cache.


Apenas para adicionar minha solução, que funciona em framework compacto (3.5) e suporta verificação de tipo em tempo de compilação :

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 alguém souber como se livrar do T valueType = new T() , T valueType = new T() feliz em ver uma solução.

Uma ligação seria assim:

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

Se você precisar de verificação de velocidade e tipo no tempo de compilação e de execução, esse método auxiliar será melhor do que usar o LINQ para converter 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[];
}

E você pode usá-lo como abaixo:

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

Claro que você pode retornar IEnumerable<T> , mas isso não lhe compra nada aqui.


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

(A resposta atual aceita tem um elenco que eu não acho que seja necessário (embora eu possa estar errado).)


Eu não tenho a opinião de que isso é melhor, ou mesmo bom, apenas afirmando outra solução.

Se os valores de enum variam estritamente de 0 a n - 1, uma 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;
    }
}

Se os valores de enum forem contíguos e você puder fornecer o primeiro e o último elemento do enum, então:

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

mas isso não é estritamente enumerando, apenas looping. O segundo método é muito mais rápido que qualquer outra abordagem ...


E se você souber que o tipo será um enum , mas não sabe qual é o tipo exato em tempo de compilação?

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

O método getListOfEnum usa a reflexão para pegar qualquer tipo de enum e retorna um IEnumerable de todos os valores 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));
}

Eu sei que é um pouco confuso, mas se você é fã de one-liners, aqui está um:

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

Eu acho que isso é mais eficiente do que outras sugestões porque GetValues() não é chamado sempre que você tiver um loop. Também é mais conciso. E você recebe um erro em tempo de compilação e não uma exceção de tempo de execução se Suit não for um enum .

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

EnumLoop tem essa definição 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]);
        }
    }
}

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

enum tipos de enum são chamados de "tipos de enumeração" não porque sejam contêineres que "enumeram" valores (que não são), mas porque são definidos enumerando os valores possíveis para uma variável desse tipo.

(Na verdade, isso é um pouco mais complicado do que isso - os tipos enum são considerados como um tipo inteiro "subjacente", o que significa que cada valor enum corresponde a um valor inteiro (isso é tipicamente implícito, mas pode ser especificado manualmente). de certa forma, para que você pudesse inserir qualquer número inteiro desse tipo na variável enum, mesmo que não seja um valor "nomeado".)

O método System.Enum.GetNames pode ser usado para recuperar uma matriz de seqüências de caracteres que são os nomes dos valores enum, como o nome sugere.

Edição: deveria ter sugerido o método System.Enum.GetValues vez disso. Oops


Esta questão aparece no capítulo 10 do " C # Step by Step 2013 "

O autor usa um loop duplo para iterar através de um par de Enumeradores (para criar um baralho cheio 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);
            }
        }
    }
}

Nesse caso, Suit e Value são as duas enumerações:

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

e PlayingCard é um objeto de carta com um Suit e Value definidos:

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

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




enumeration