27 Pytanie: Jak wyliczyć wyliczenie w C #?

pytanie utworzone w Mon, May 27, 2019 12:00 AM

Jak możesz wyliczyć enum w C #?

Np. następujący kod się nie kompiluje:

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

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

I podaje następujący błąd czasu kompilacji:

  

„Garnitur” jest „typem”, ale jest używany jak „zmienna”

Nie działa w przypadku słowa kluczowego Suit, drugiego.

    
3469
  1. 2009-08-04 14: 10: 45Z
  2. Możesz sprawdzić tajniki wyliczeń C # , które omawiają to, a także inne przydatne enum ciekawostki
    2018-05-14 12: 53: 13Z
  3. LOL miał DOKŁADNIE to samo pytanie (zgadnij, że chcesz robić coś z pokerem?): D
    2019-02-05 10: 49: 25Z
27 Odpowiedzi                              27                         
 
foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit)))
{
}

Uwaga : rzut na (Suit[]) nie jest konieczny, ale sprawia, że ​​kod jest szybszy o 0,5 ns.

    
4285
2019-02-05 15: 18: 51Z
  1. To nie działa, jeśli masz listę zduplikowanych wartości na liście wyliczającej.
    2012-06-17 03: 50: 38Z
  2. Chcę tylko podkreślić, że to niestety nie zadziała w Silverlight, ponieważ biblioteka Silverlight nie zawiera enum.GetValues. W tym przypadku musisz użyć refleksji.
    2013-10-17 05: 50: 55Z
  3. @ Jessy to robi działa w przypadku zduplikowanych sytuacji, takich jak enum E {A = 0, B = 0}. Enum.GetValues powoduje zwrócenie dwóch wartości, chociaż są one takie same. E.A == E.B jest prawdą, więc nie ma rozróżnienia. Jeśli chcesz poszczególnych nazw, powinieneś szukać Enum.GetNames.
    2013-11-07 09: 25: 53Z
  4. Jeśli masz duplikaty /synonimy w enumie i chcesz inne zachowanie, możesz użyć rozszerzenia Distinct Linq (od .NET 3.5), więc foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }.
    2014-06-12 08: 46: 39Z
  5. Popełniłem błąd, próbując użyć var dla typu. Kompilator stworzy zmienną Object zamiast enum. Wyświetl jawnie typ wyliczenia.
    2016-01-08 22: 57: 08Z

Wygląda na to, że naprawdę chcesz wydrukować nazwy każdego wyliczenia, a nie wartości. W takim przypadku Enum.GetNames() wydaje się właściwym podejściem.

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

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

Przy okazji, zwiększanie wartości nie jest dobrym sposobem na wyliczenie wartości wyliczenia. Powinieneś to zrobić zamiast tego.

Zamiast tego używałbym Enum.GetValues(typeof(Suit)).

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

public void PrintAllSuits()
{
    foreach (var suit in Enum.GetValues(typeof(Suits)))
    {
        System.Console.WriteLine(suit.ToString());
    }
}
    
638
2014-02-10 18: 04: 36Z
  1. Składnia VB tutaj: link
    2018-09-09 02: 11: 27Z
  2. Wziąłem twoją wersję z małymi następującymi zmianami z mojej strony: Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray(). W takim przypadku mogę iterować tablicę Suits elementów enum, a nie łańcuchów.
    2019-06-24 12: 57: 58Z

Zrobiłem kilka rozszerzeń dla łatwego użycia enum, może ktoś może go użyć ...

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

Sama enum musi być ozdobiona FlagsAttribute  

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}
    
314
2010-12-07 16: 53: 32Z
  1. Jeden liner dla pierwszej metody rozszerzenia; nie jest bardziej leniwy. return Enum.GetValues ​​(typeof (T)). Cast < T > ();
    2010-06-22 09: 29: 29Z
  2. Alternatywnie możesz również użyć OfType: Enum.GetValues ​​(typeof (T)). OfType < T > (). Szkoda, że ​​nie istnieje ogólna wersja GetValues ​​(T) (), a wtedy byłoby jeszcze lepiej.
    2011-01-10 22: 38: 58Z
  3. Może ktoś mógłby pokazać, jak korzystać z tych rozszerzeń? Kompilator nie pokazuje metod rozszerzenia na enum EnumExample.
    2013-02-12 08: 01: 30Z
  4. czy każdy może dodać przykład wykorzystania tych funkcji?
    2013-09-23 13: 01: 07Z
  5. + 1 dla kodu wielokrotnego użytku: przykłady - zapisz te metody rozszerzenia w bibliotece i odwołaj się do niego [Flags] public enum mytypes {name1, name2}; List < string > myTypeNames = mytypes.GetAllItems ();
    2013-10-22 06: 55: 57Z

Niektóre wersje środowiska .NET nie obsługują Enum.GetValues. Oto dobre obejście z Ideas 2.0: Enum.GetValues ​​w 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;
}

Jak w przypadku każdego kodu związanego z odbiciem powinieneś podjąć kroki, aby upewnić się, że działa tylko raz, a wyniki są buforowane.

    
167
2019-03-08 04: 39: 57Z
  1. Dlaczego nie użyjesz tutaj słowa yield zamiast tego, by utworzyć listę?
    2011-01-16 22: 18: 16Z
  2. lub krótszy: return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>();
    2013-11-07 09: 21: 54Z
  3. @ nawfal: Linq nie jest dostępny .Net CF 2.0.
    2014-05-23 15: 16: 16Z
  4. @ Ekevoo Jak powiązać te wartości wyliczeniowe z DropDownList w MVC?
    2015-12-16 18: 36: 54Z

Dlaczego nikt nie korzysta z Cast<T>?

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

Tam masz IEnumerable<Suit>.

    
99
2014-07-25 12: 12: 52Z
  1. To jest całkiem fajne, jeśli możesz użyć LINQ ...
    2017-01-19 17: 59: 03Z
  2. Działa to również w klauzuli from i deklaratorze nagłówka foreach.
    2017-12-11 11: 58: 01Z

Myślę, że jest to bardziej wydajne niż inne sugestie, ponieważ GetValues() nie jest wywoływany za każdym razem, gdy masz pętlę. Jest także bardziej zwięzły. I otrzymujesz błąd czasu kompilacji, a nie wyjątek czasu wykonywania, jeśli Suit nie jest enum.

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

EnumLoop ma tę całkowicie ogólną definicję:

 
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]);
        }
    }
}
    
91
2016-03-17 19: 41: 48Z
  1. Uważaj na używanie takich typów. Jeśli spróbujesz użyć EnumLoop z jakimś typem, który nie jest enum, kompiluje się dobrze, ale rzuca wyjątek w czasie wykonywania.
    2012-02-06 12: 09: 08Z
  2. Dziękuję svick. Wyjątki środowiska wykonawczego będą występować wraz z innymi odpowiedziami na tej stronie ... z wyjątkiem tego, ponieważ dodałem "where Key: struct, IConvertible", aby w większości przypadków uzyskać błąd czasu kompilacji.
    2012-02-07 12: 13: 14Z
  3. Nie, GetValues ​​() jest wywoływane tylko raz w foreach.
    2012-07-30 11: 25: 48Z
  4. James, zniechęciłbym twoją klasę, ponieważ sprytny jest miło pisać, ale w kodzie produkcyjnym, który wielu ludzi będzie utrzymywać i aktualizować, sprytna jest dodatkowa praca. Jeśli przyniesie to znaczne oszczędności lub będzie dużo używane - więc oszczędności są duże i ludzie się z nim zapoznają - jest tego warte, ale w większości przypadków spowalnia ludzi próbujących czytać i aktualizować kod oraz wprowadza możliwe błędy źródłowe w przyszłości. Mniej kodu jest lepsze :) mniej złożoności jest jeszcze lepsza.
    2015-01-19 04: 00: 32Z
  5. @ GrantM Dlaczego? Ten kod nie jest ani skomplikowany, ani niewiarygodnie krótki. Ponadto pisanie klasy pozwoli na jeszcze krótsze iteracje kodu przy użyciu, jak na jego przykładzie. Jest to bardzo czyste, jeśli nie możesz zaktualizować tego kodu, prawdopodobnie nie możesz zaktualizować żadnego kodu firmy.
    2017-05-16 18: 30: 32Z

Nie dostaniesz Enum.GetValues() w Silverlight.

Original Blog Post autorstwa Einara Ingebrigtsena :

 
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();
    }
}
    
72
2016-01-15 14: 11: 29Z
  1. Ładne rozwiązanie, ale niektóre refaktoryzacje będą lepsze! :)
    2013-11-07 09: 10: 08Z
  2. Używam .NET framework 4.0 i amp; silverlight enum.getvalues ​​działa, kod którego użyłem to --- > enum.GetValues ​​(typeof (enum))
    2015-12-30 06: 41: 18Z
  3. Począwszy od C # 7.3 (Visual Studio 2017 ≥ 15.7), można użyć where T: Enum
    2018-07-27 14: 59: 35Z

Aby dodać moje rozwiązanie, które działa w środowisku Compact Framework (3.5) i obsługuje sprawdzanie typów w czasie kompilacji :

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

- Jeśli ktoś wie, jak pozbyć się T valueType = new T(), z przyjemnością zobaczę rozwiązanie.

Połączenie wyglądałoby tak:

 
List<MyEnum> result = Utils.GetEnumValues<MyEnum>();
    
54
2014-01-30 04: 43: 03Z
  1. a co z użyciem T valueType = default(T)?
    2010-07-07 14: 17: 17Z
  2. Świetnie, nawet nie znałem tego słowa kluczowego. Zawsze miło nauczyć się czegoś nowego. Dziękuję Ci! Czy zawsze zwraca odwołanie do tego samego obiektu, czy tworzy nową instancję za każdym razem, gdy wywoływana jest instrukcja domyślna? Jak dotąd nie znalazłem w sieci niczego, ale jeśli za każdym razem tworzy nową instancję, to w pewnym sensie pokonuje cel, którego szukałem (mając jeden liner ^^).
    2010-07-08 06: 48: 46Z
  3. Czy nie stworzyłoby to nowej instancji dla każdej iteracji w wyliczeniu?
    2011-06-28 15: 04: 18Z
  4. - 1 for "obsługuje sprawdzanie typów w czasie kompilacji:". Jaki typ sprawdza? To działałoby dla każdego new() T. Ponadto, w ogóle nie potrzebujesz new T(), możesz wybrać tylko pola statyczne i zrobić .GetValue(null). Zobacz odpowiedź Aubreya.
    2014-01-30 04: 47: 52Z
  5. Począwszy od C # 7.3 (Visual Studio 2017 ≥ 15.7), można użyć where T: Enum
    2018-07-27 14: 59: 01Z

Myślę, że możesz użyć

 
Enum.GetNames(Suit)
    
49
2011-07-25 07: 46: 06Z
  1. Enum.GetValues ​​(Suits)
    2008-09-22 14: 43: 50Z
 
public void PrintAllSuits()
{
    foreach(string suit in Enum.GetNames(typeof(Suits)))
    {
        Console.WriteLine(suit);
    }
}
    
47
2017-01-09 20: 45: 39Z
  1. To wylicza ciąg znaków, nie zapomnij przekonwertować tych rzeczy z powrotem na wartość wyliczenia, aby wyliczenie mogło być wyliczone.
    2010-06-01 17: 46: 51Z
  2. Widzę, że z twojej edycji wynika, że ​​chcesz operować na samych wersjach, powyższy kod zajął się twoim oryginalnym postem.
    2010-06-04 15: 22: 08Z
 
foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }
     

Słyszałem niejasne pogłoski, że tak jest   bardzo wolno. Ktoś wie? - Orion   Edwards 15 października 2008 o 1:31 7

Myślę, że buforowanie tablicy przyspieszyłoby znacznie. Wygląda na to, że za każdym razem otrzymujesz nową tablicę (poprzez odbicie). Raczej:

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

To przynajmniej trochę szybciej, ja?

    
46
2017-10-06 07: 20: 14Z
  1. Kompilator powinien się tym zająć.
    2015-02-23 12: 57: 55Z
  2. @ StephanBijzitter Wow, czytasz dość daleko na tym :-) Zgadzam się, kompilator powinien uczynić moje rozwiązanie niepotrzebnym.
    2015-02-23 17: 52: 10Z
  3. To nie jest konieczne. Patrząc na skompilowany kod w ILSpy, kompilator zdecydowanie już to robi. Dlaczego ta odpowiedź jest w ogóle potwierdzona, a tym bardziej 35 razy?
    2018-05-08 16: 14: 22Z
  4. Został on opublikowany dawno temu. Bardzo dawno temu. Założę się, że kompilator też to rozwiązał. Ale na pewno wygląda bardziej wydajnie, prawda? ;-)
    2018-05-09 16: 58: 17Z

Trzy sposoby:

 
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

Nie wiem, dlaczego GetEnumValues został wprowadzony w instancji typu, nie jest dla mnie zbyt czytelny.


Posiadanie klasy pomocniczej, takiej jak Enum<T>, jest dla mnie najbardziej czytelne i niezapomniane:

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

Teraz dzwonisz:

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

Można również użyć rodzaju buforowania, jeśli liczy się wydajność, ale nie spodziewam się, że będzie to w ogóle problem

 
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)));
    }
}
    
25
2017-01-09 23: 43: 50Z
  1. To jest ładne podsumowanie metod. Myślę jednak, że powinieneś w to połączyć swoją drugą odpowiedź. Prawda jest taka, że ​​wyliczenie jest wyjątkowe i pętla przez nie jest często (zwykle) tak samo ważna jak wyliczanie, ponieważ wiesz, że wartości nigdy się nie zmienią. IOW, Jeśli masz enum, które zmienia się cały czas, wybrałeś niewłaściwą konstrukcję danych na początek.
    2017-12-19 17: 03: 01Z

Co do diabła wrzucę moje dwa pensy, po prostu łącząc najlepsze odpowiedzi, łączę bardzo proste rozszerzenie

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

Czystość prosta i szybki komentarz @ Jeppe-Stig-Nielsena.

    
22
2019-03-20 14: 19: 44Z
  1. Począwszy od C # 7.3 (Visual Studio 2017 ≥ 15.7), można użyć where T: Enum
    2018-07-27 14: 57: 05Z

Używam ToString (), a następnie dzielę i analizuję tablicę spit w flagach.

 
[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);
}
    
21
2015-11-18 15: 51: 19Z

Istnieją dwa sposoby iteracji Enum:

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

Pierwsza da Ci wartości w postaci formularza w postaci object , a druga da Ci wartości w postaci tablicy String .

Użyj go w pętli foreach jak poniżej:

 
foreach(var value in values)
{
    //Do operations here
}
    
21
2017-01-13 07: 12: 47Z
  1. Kto głosuje w dół .... działa doskonale ... i przynajmniej dodaj komentarz, co jego zdaniem jest złe?
    2016-04-27 09: 21: 05Z
  2. downvoting bez podania przyczyny jest naprawdę niesprawiedliwy
    2016-06-20 06: 19: 01Z
  3. Być może, ponieważ jest to już ujęte w wielu odpowiedziach? Nie róbmy odpowiedzi zbędnych.
    2017-05-17 15: 38: 33Z
  4. @ nawfal yes może być omówiony w innych odpowiedziach, ale w większości z nich nie został zawarty dobrze.
    2017-05-18 05: 39: 08Z

Nie uważam, że jest to lepsze, a nawet dobre, tylko podanie innego rozwiązania.

Jeśli wartości wyliczeniowe mieszczą się w przedziale od 0 do n - 1, ogólna alternatywa:

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

Jeśli wartości wyliczeniowe są ciągłe i możesz podać pierwszy i ostatni element wyliczenia, to:

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

ale to nie jest ściśle wyliczane, tylko zapętlanie. Druga metoda jest znacznie szybsza niż jakakolwiek inna metoda ...

    
15
2013-01-25 00: 05: 04Z

Jeśli potrzebujesz sprawdzania szybkości i typu w czasie kompilacji i uruchamiania, ta metoda pomocy jest lepsza niż użycie LINQ do rzucania każdego elementu:

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

I możesz go użyć jak poniżej:

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

Oczywiście możesz zwrócić IEnumerable<T>, ale nic tu nie kupujesz.

    
15
2016-01-17 12: 11: 23Z
  1. Począwszy od C # 7.3 (Visual Studio 2017 ≥ 15.7), można użyć where T: Enum
    2018-07-27 14: 57: 51Z

Oto działający przykład tworzenia wybranych opcji dla 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()
      };
    
12
2015-10-02 14: 00: 04Z
 
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}

(Aktualna zaakceptowana odpowiedź ma obsadę, o której nie sądzę jest potrzebne (chociaż mogę się mylić).)

    
10
2016-01-17 12: 12: 22Z

To pytanie pojawia się w rozdziale 10 „ C # Krok po kroku 2013

Autor używa podwójnej pętli do iteracji przez parę wyliczników (aby utworzyć pełną talię kart):

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

W tym przypadku Suit i Value są wyliczeniami:

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

i PlayingCard to obiekt karty o zdefiniowanym Suit i Value:

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

    public PlayingCard(Suit s, Value v)
    {
        this.suit = s;
        this.value = v;
    }
}
    
9
2017-01-13 07: 22: 21Z
  1. czy to zadziała, jeśli wartości w enum nie są sekwencyjne?
    2017-02-01 09: 50: 41Z

Wiem, że to trochę bałagan, ale jeśli jesteś fanem jednowierszowych, oto jedno:

 
((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));
    
8
2015-05-15 11: 31: 39Z
  1. Czy to seplenienie ?
    2019-03-01 15: 02: 34Z

Co jeśli wieszTypem będzie enum, ale nie wiesz, jaki dokładnie jest typ w czasie kompilacji?

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

Metoda getListOfEnum używa odbicia do pobierania dowolnego typu wyliczeniowego i zwraca IEnumerable wszystkich wartości wyliczeniowych.

Użycie:

 
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));
}
    
7
2015-10-01 10: 21: 40Z

Prosty i ogólny sposób konwertowania enum na coś, z czym możesz współdziałać:

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

A potem:

 
var enums = EnumHelper.ToList<MyEnum>();
    
7
2016-10-25 14: 12: 37Z
  1. A Dictionary nie jest dobrym pomysłem: jeśli masz Enum jak enum E { A = 0, B = 0 }, wartość 0 jest dodawana 2 razy, generując ArgumentException (nie możesz dodać tego samego Key na Dictionary 2 lub więcej razy!).
    2016-10-25 13: 00: 14Z
  2. Po co zwracać Dictionary<,> z metody o nazwie ToList? Również dlaczego nie zwrócić Dictionary<T, string>?
    2017-12-11 11: 53: 47Z

Dodaj metodę public static IEnumerable<T> GetValues<T>() do swojej klasy, na przykład

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

wywołaj i przekaż swoje wyliczenie, teraz możesz przeglądać je za pomocą foreach

 
 public static void EnumerateAllSuitsDemoMethod()
 {
     // custom method
     var foos = GetValues<Suit>(); 
     foreach (var foo in foos)
     {
         // Do something
     }
 }
    
4
2017-10-06 07: 18: 22Z

enum typów nazywanych jest „typami wyliczającymi”, nie dlatego, że są kontenerami, które „wyliczają” wartości (które nie są), ale dlatego, że są zdefiniowane przez wyliczanie możliwych wartości dla zmiennej tego typu.

(Właściwie jest to nieco bardziej skomplikowane niż to - uważa się, że typy wyliczeniowe mają typ „podstawowy”, co oznacza, że ​​każda wartość wyliczeniowa odpowiada wartości całkowitej (jest to zazwyczaj niejawne, ale można je ręcznie określić). C # został zaprojektowany w taki sposób, że możesz dowolną liczbę całkowitą tego typu do zmiennej wyliczającej, nawet jeśli nie jest to wartość „nazwana”.)

System.Enum Metoda .GetNames może być użyta do pobrania tablicy ciągów, które są nazwami wartości wyliczeniowych, jak sugeruje nazwa.

EDYCJA: Powinien był zasugerować 1

2018-01-16 20: 14: 54Z
  1. Chociaż twoja odpowiedź sama w sobie jest poprawna, tak naprawdę nie odnosi się do pierwotnego pytania PO. Metoda GetNames rzeczywiście zwraca tablicę łańcuchów, ale OP wymaga modułu wyliczającego poprzez wartości.
    2018-01-15 09: 30: 15Z
  2. @ SilviuPreda: Edited. Powinien być GetValues ​​zamiast GetNames.
    2018-01-16 20: 17: 27Z

Możesz również bezpośrednio powiązać się z publicznymi statycznymi członkami enum, używając refleksji:

 
typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static)
    .ToList().ForEach(x => DoSomething(x.Name));
    
0
2017-01-09 23: 39: 34Z

spróbuj użyć foreach (var item w Enum.GetValues ​​(typeof (Suits)))

    
- 2
2019-06-18 04: 12: 58Z
  1. To już zostało wspomniane w wielu odpowiedziach powyżej. Sprawdź odpowiedzi przed wysłaniem.
    2019-06-11 06: 44: 43Z
źródło umieszczone tutaj