27 Вопрос: Как мне перечислить перечисление в C #?

вопрос создан в Mon, May 27, 2019 12:00 AM

Как вы можете перечислить enum в C #?

например. следующий код не компилируется:

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

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

И выдает следующую ошибку во время компиляции:

  

«Костюм» - это «тип», но используется как «переменная»

Сбой ключевого слова Suit - второго.

    
3469
  1. Смотрите также ... stackoverflow.com/questions/972307/…
    2009-08-04 14: 10: 45Z
  2. Возможно, вы захотите проверить входы и выходы перечислений C # , в которых обсуждается это, а также другие полезные кусочки перечислений
    2018-05-14 12: 53: 13Z
  3. У LOL точно такой же вопрос (угадайте, что вы хотите сделать с покером?): D
    2019-02-05 10: 49: 25Z
27 ответов                              27                         
 
foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit)))
{
}

Примечание : приведение к (Suit[]) не является строго необходимым, но делает код на 0,5 нс быстрее.

    
4285
2019-02-05 15: 18: 51Z
  1. Это не работает, если в списке перечислителей есть повторяющиеся значения.
    2012-06-17 03: 50: 38Z
  2. Я просто хочу отметить, что это, к сожалению, не будет работать в silverlight, поскольку библиотека silverlight не содержит enum.GetValues. Вы должны использовать отражение в этом случае.
    2013-10-17 05: 50: 55Z
  3. @ Джесси, это делает работу в случае дублирующих ситуаций, таких как enum E {A = 0, B = 0}. Enum.GetValues приводит к возвращению двух значений, хотя они одинаковы. E.A == E.B верно, поэтому нет различия. Если вам нужны индивидуальные имена, вам нужно искать Enum.GetNames.
    2013-11-07 09: 25: 53Z
  4. Затем, если в вашем перечислении есть дубликаты /синонимы, и вы хотите другое поведение, вы можете использовать расширение Linq's Distinct (начиная с .NET 3.5), то есть foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }.
    2014-06-12 08: 46: 39Z
  5. Я сделал ошибку, пытаясь использовать var для типа. Компилятор сделает переменную Object вместо перечисления. Перечислите тип перечисления явно.
    2016-01-08 22: 57: 08Z

Мне кажется, вы действительно хотите распечатать имена каждого перечисления, а не значения. В этом случае Enum.GetNames() кажется правильным подходом.

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

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

Кстати, увеличение значения не является хорошим способом для перечисления значений перечисления. Вы должны сделать это вместо этого.

Я бы использовал 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. Синтаксис VB здесь: ссылка
    2018-09-09 02: 11: 27Z
  2. Я взял вашу версию с небольшими изменениями с моей стороны: Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray(). В этом случае я могу перебирать массив из Suits перечисляемых элементов, а не строк.
    2019-06-24 12: 57: 58Z

Я сделал несколько расширений для простого использования enum, может быть, кто-то может использовать его ...

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

Само перечисление должно быть оформлено с помощью FlagsAttribute  

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}
    
314
2010-12-07 16: 53: 32Z
  1. Один вкладыш для первого метода расширения; это больше не ленивый. вернуть Enum.GetValues ​​(typeof (T)). Cast &Lt; T > ();
    2010-06-22 09: 29: 29Z
  2. В качестве альтернативы вы также можете использовать OfType: Enum.GetValues ​​(typeof (T)). OfType < T > (). Жаль, что нет универсальной версии GetValues ​​< T > (), тогда она была бы еще более привлекательной.
    2011-01-10 22: 38: 58Z
  3. Может быть, кто-то может показать, как использовать эти расширения? Компилятор не показывает методы расширения для перечисления EnumExample.
    2013-02-12 08: 01: 30Z
  4. Кто-нибудь может добавить пример использования этих функций?
    2013-09-23 13: 01: 07Z
  5. + 1 для многократно используемого кода: примеры - сохранить эти методы расширения в библиотеке и сослаться на них [Flags] public enum mytypes {name1, name2}; Список &л; строка &GT; myTypeNames = mytypes.GetAllItems ();
    2013-10-22 06: 55: 57Z

Некоторые версии .NET Framework не поддерживают Enum.GetValues. Вот хороший обходной путь из Идеи 2.0: Enum.GetValues ​​в 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;
}

Как и в любом коде, который включает отражение , вы должны предпринять шаги, чтобы убедиться, что он запускается только один раз и результаты кэшируются.

    
167
2019-03-08 04: 39: 57Z
  1. Почему бы не использовать здесь ключевое слово yield вместо создания списка?
    2011-01-16 22: 18: 16Z
  2. или короче: return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>();
    2013-11-07 09: 21: 54Z
  3. @ nawfal: Linq недоступен .Net CF 2.0.
    2014-05-23 15: 16: 16Z
  4. @ Ekevoo Как связать значения этого перечисления с DropDownList в MVC?
    2015-12-16 18: 36: 54Z

Почему никто не использует Cast<T>?

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

Вот, пожалуйста, IEnumerable<Suit>.

    
99
2014-07-25 12:12:52Z
  1. Это очень круто, если вы можете использовать LINQ ...
    2017-01-19 17: 59: 03Z
  2. Это также работает в предложении from и в объявителе заголовка foreach.
    2017-12-11 11: 58: 01Z

Я думаю, что это более эффективно, чем другие предложения, потому что GetValues() не вызывается каждый раз, когда у вас есть цикл. Это также более кратко. И вы получите ошибку времени компиляции, а не исключение времени выполнения, если Suit не является enum.

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

EnumLoop имеет это полностью общее определение:

 
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. Осторожнее с использованием таких обобщений. Если вы попытаетесь использовать EnumLoop с каким-либо типом, который не является enum, он скомпилируется нормально, но выдает исключение во время выполнения.
    2012-02-06 12: 09: 08Z
  2. Спасибо, svick. Исключения во время выполнения будут фактически встречаться с другими ответами на этой странице ... кроме этого, потому что я добавил "где ключ: структура, IConvertible", чтобы вы получили ошибку времени компиляции в большинстве случаев.
    2012-02-07 12: 13: 14Z
  3. Нет, GetValues ​​() вызывается только один раз в foreach.
    2012-07-30 11: 25: 48Z
  4. Джеймс, я бы не поощрял ваш класс, потому что умный писать приятно, но в рабочем коде, который многие люди будут поддерживать и обновлять, умный - это дополнительная работа. Если это приводит к значительным сбережениям или будет использоваться много - таким образом, сбережения велики, и люди будут с ними знакомы - это того стоит, но в большинстве случаев это замедляет людей, пытающихся прочитать и обновить код, и представляет возможную источник ошибок в будущем. Меньше кода - лучше :) Меньше сложности - еще лучше.
    2015-01-19 04: 00: 32Z
  5. @ GrantM Почему? Этот код не сложен и невероятно короток. Вдобавок к этому, написание класса один раз позволит еще более короткие итерации кода с использованием, как в его примере. Это очень чисто, если вы не можете обновить этот код, вы, вероятно, не можете обновить любой код компании.
    2017-05-16 18: 30: 32Z

Вы не получите Enum.GetValues() в Silverlight.

Оригинальное сообщение в блоге Эйнара Ингебригтсена :

 
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. Хорошее решение, но некоторый рефакторинг будет лучше! :)
    2013-11-07 09: 10: 08Z
  2. Я использую .NET Framework 4.0 & Silverlight enum.getvalues ​​работает, код, который я использовал, --- > enum.GetValues ​​(TypeOf (перечисление))
    2015-12-30 06: 41: 18Z
  3. Начиная с C # 7.3 (Visual Studio 2017 ≥ v15.7), можно использовать where T: Enum
    2018-07-27 14: 59: 35Z

Просто добавлю мое решение, которое работает в компактной среде (3.5) и поддерживает проверку типов во время компиляции :

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

- Если кто-нибудь знает, как избавиться от T valueType = new T(), я был бы рад найти решение.

Звонок будет выглядеть так:

 
List<MyEnum> result = Utils.GetEnumValues<MyEnum>();
    
54
2014-01-30 04: 43: 03Z
  1. как насчет использования T valueType = default(T)?
    2010-07-07 14: 17: 17Z
  2. Отлично, я даже не знал этого ключевого слова. Всегда приятно узнавать что-то новое. Спасибо! Всегда ли он возвращает ссылку на один и тот же объект или создает новый экземпляр каждый раз, когда вызывается оператор по умолчанию? До сих пор я не нашел в сети ничего об этом, но если он каждый раз создает новый экземпляр, он как бы побеждает цель, которую я искал (имея однострочник ^^).
    2010-07-08 06: 48: 46Z
  3. Разве это не создаст новый экземпляр для каждой итерации по перечислению?
    2011-06-28 15: 04: 18Z
  4. - 1 для "поддерживает проверку типов во время компиляции:". Какой тип проверки? Это будет работать для любого new() T. Кроме того, вам вообще не нужен new T(), вы можете выбрать только статические поля и сделать .GetValue(null). Смотрите ответ Обри.
    2014-01-30 04: 47: 52Z
  5. Начиная с C # 7.3 (Visual Studio 2017 ≥ v15.7), можно использовать where T: Enum
    2018-07-27 14: 59: 01Z

Я думаю, что вы можете использовать

 
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. Это перечисляет строку, не забудьте преобразовать эти вещи обратно в значение перечисления, чтобы перечисление можно было перечислить.
    2010-06-01 17: 46: 51Z
  2. Я вижу из ваших изменений, что вы действительно хотите работать с самими перечислениями, приведенный выше код адресован вашему исходному сообщению.
    2010-06-04 15: 22: 08Z
 
foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }
     

Я слышал смутные слухи, что это   очень медленно Кто-нибудь знает? - Орион   Эдвардс 15 октября 2008 года в 1:31 7

Я думаю, что кэширование массива значительно ускорит его. Похоже, вы получаете новый массив (через отражение) каждый раз. Скорее всего:

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

Это, по крайней мере, немного быстрее, да?

    
46
2017-10-06 07: 20: 14Z
  1. Хотя об этом должен позаботиться компилятор.
    2015-02-23 12: 57: 55Z
  2. @ StephanBijzitter Ничего себе, вы читаете довольно далеко об этом :-) Я согласен, компилятор должен сделать мое решение ненужным.
    2015-02-23 17: 52: 10Z
  3. Это не обязательно. Глядя на скомпилированный код в ILSpy, компилятор определенно уже делает это. Почему за этот ответ вообще проголосовали, а тем более 35 раз?
    2018-05-08 16: 14: 22Z
  4. Это было давно проголосовано. Давным-давно Я бы поспорил, что компилятор тоже решил бы это тогда. Но ведь он выглядит более производительно, не так ли? ; -)
    2018-05-09 16: 58: 17Z

Три способа:

 
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

Не знаю, почему GetEnumValues был введен для экземпляра типа, для меня он совсем не читается.

Наличие вспомогательного класса, такого как Enum<T>, является для меня самым читаемым и запоминающимся:

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

Теперь вы звоните:

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

Можно также использовать своего рода кэширование, если производительность имеет значение, но я не ожидаю, что это вообще будет проблемой

 
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. Это хорошая сводка методов. Я думаю, что вы должны объединить свой другой ответ в этом, хотя. Правда в том, что перечисления являются особыми, и их циклирование часто (обычно) так же верно, как перечисление, потому что вы знаете, что значения никогда не изменятся. IOW, если у вас есть enum, который постоянно меняется, значит, вы выбрали неправильную конструкцию данных для начала.
    2017-12-19 17: 03: 01Z

Что, черт возьми, я добавлю в свои два пенса, просто объединив самые верхние ответы, и получу очень простое расширение

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

Очистите просто и быстро с помощью комментария @ Jeppe-Stig-Nielsen.

    
22
2019-03-20 14: 19: 44Z
  1. Начиная с C # 7.3 (Visual Studio 2017 ≥ v15.7), можно использовать where T: Enum
    2018-07-27 14: 57: 05Z

Я использую ToString (), затем разделяю и разбираю массив spit по флагам.

 
[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

Существует два способа перебора Enum:

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

Первый даст вам значения в виде массива object , а второй даст вам значения в виде массива String .

Используйте его в цикле foreach, как показано ниже:

 
foreach(var value in values)
{
    //Do operations here
}
    
21
2017-01-13 07: 12: 47Z
  1. Кто отказывается голосовать ... это работает отлично ... и, по крайней мере, добавить комментарий, что они считают неправильным?
    2016-04-27 09: 21: 05Z
  2. голосование без объяснения причин действительно несправедливо
    2016-06-20 06: 19: 01Z
  3. Может быть, потому что это уже описано во многих ответах? Давайте не будем делать ответы излишними.
    2017-05-17 15: 38: 33Z
  4. @ nawfal yes может быть рассмотрен в других ответах, хотя в большинстве из них он не очень хорошо завершен.
    2017-05-18 05: 39: 08Z

Я не придерживаюсь мнения, что это лучше или даже хорошо, просто заявляю еще одно решение.

Если значения перечисления строго находятся в диапазоне от 0 до n - 1, общая альтернатива:

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

Если значения перечисления смежны и вы можете указать первый и последний элемент перечисления, то:

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

но это не строго перечисление, просто цикл. Второй способ намного быстрее, чем любой другой подход ...

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

Если вам нужна проверка скорости и типа во время сборки и выполнения, этот вспомогательный метод лучше, чем использование LINQ для приведения каждого элемента:

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

И вы можете использовать его, как показано ниже:

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

Конечно, вы можете вернуть IEnumerable<T>, но здесь вы ничего не купите.

    
15
2016-01-17 12: 11: 23Z
  1. Начиная с C # 7.3 (Visual Studio 2017 ≥ v15.7), можно использовать where T: Enum
    2018-07-27 14: 57: 51Z

вот рабочий пример создания опций выбора для 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)))
{
}

(у текущего принятого ответа есть актерский состав, который я не думаю, необходимо (хотя я могу и ошибаться).

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

Этот вопрос появляется в главе 10 " C # Step by Step 2013 "

Автор использует двойной цикл for для перебора пары перечислителей (для создания полной колоды карт):

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

В этом случае Suit и Value являются перечислениями:

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

и PlayingCard - это объект карты с определенными Suit и 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. это сработает, если значения в enum не являются последовательными?
    2017-02-01 09: 50: 41Z

Я знаю, что это немного грязно, но если вы фанат однострочников, вот один из них:

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

Что если вы знаете типбудет enum, но вы не знаете точный тип во время компиляции?

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

Метод getListOfEnum использует отражение, чтобы взять любой тип перечисления и возвращает IEnumerable всех значений перечисления.

Использование:

 
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

Простой и общий способ преобразования перечисления во что-то, с чем вы можете взаимодействовать:

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

А потом:

 
var enums = EnumHelper.ToList<MyEnum>();
    
7
2016-10-25 14: 12: 37Z
  1. Dictionary не очень хорошая идея: если у вас Enum, например enum E { A = 0, B = 0 }, значение 0 добавляется 2 раза, создавая ArgumentException (вы не можете добавить те же Key на Dictionary 2 или более раз!).
    2016-10-25 13: 00: 14Z
  2. Зачем возвращать Dictionary<,> из метода с именем ToList? И почему бы не вернуть Dictionary<T, string>?
    2017-12-11 11: 53: 47Z

Добавьте метод public static IEnumerable<T> GetValues<T>() в свой класс, например

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

позвоните и передайте ваше перечисление, теперь вы можете перебрать его, используя 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 типов называются «типами перечисления» не потому, что они являются контейнерами, «перечисляющими» значения (которые они не являются), а потому, что они определены перечислением возможных значений для переменной этот тип.

(На самом деле, это немного сложнее - считается, что типы перечисления имеют «базовый» целочисленный тип, что означает, что каждое значение перечисления соответствует целочисленному значению (обычно это неявное, но может быть указано вручную). C # был разработан таким образом, чтобы вы могли вставить любое целое число этого типа в переменную enum, даже если это не «именованное» значение.)

System.Enum Метод .GetNames можно использовать для получения массива строк, которые являются именами значений перечисления, как следует из названия.

РЕДАКТИРОВАТЬ: должен был предложить Вместо этого используется метод System.Enum.GetValues ​​. К сожалению.

    
1
2018-01-16 20: 14: 54Z
  1. Несмотря на то, что ваш ответ верен сам по себе, он на самом деле не отвечает на первоначальный вопрос ОП. Метод GetNames возвращает строковый массив, но для OP требуется перечислитель через значения.
    2018-01-15 09: 30: 15Z
  2. @ SilviuPreda: отредактировано. Это должны были быть GetValues ​​вместо GetNames.
    2018-01-16 20: 17: 27Z

Кроме того, вы можете привязать к общедоступным статическим членам перечисления напрямую с помощью отражения:

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

попробуйте использовать foreach (элемент var в Enum.GetValues ​​(typeof (Suits)))

    
- 2
2019-06-18 04: 12: 58Z
  1. Это уже упоминалось во многих ответах выше. Пожалуйста, проверьте ответы перед публикацией.
    2019-06-11 06: 44: 43Z
источник размещен Вот