Итерация по типу перечисления

Возможный дубликат:
Как перечислить перечисление?

Я не знаю, можно ли делать то, что я хочу делать, но я думаю, почему бы и нет.

У меня есть пример перечисления:

public enum Animals {
    Cat,
    Dog,
    ...
}

То, что я хочу сделать, это перебрать в этом перечислении. Я хочу, чтобы он работал так:

foreach( var type in Animals ) {
    Console.WriteLine( type.toString() );
}

и вывод будет:

 Cat
 Dog

Возможно ли это? Я не хочу помещать каждый элемент в массив, а затем итерацию, я хочу итерации непосредственно на этом перечислении.

+18
источник поделиться
5 ответов

EDIT: Обратите внимание, что в течение этого ответа я переименовал Animals в Animal. Согласно соглашениям .NET, только перечисления на основе флагов должны иметь множественное имя.

Вы можете использовать Enum.GetValues():

foreach (var type in (Animal[]) Enum.GetValues(typeof(Animal)) {
    Console.WriteLine(type.toString());
}

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

foreach (Animal type in Enum.GetValues(typeof(Animal)) {
    Console.WriteLine(type.toString());
}

Но теперь вы не обнаружите ошибок как можно раньше. Например:

foreach (Animal type in Enum.GetValues(typeof(SomeEmptyEnum)) {
    Console.WriteLine(type.toString());
}

Где SomeEmptyEnum (очевидно) пустой тип перечисления. Здесь GetValues возвращает пустой массив типа SomeEmptyEnum[]. В приведенном выше коде будет только проверяться, что каждый член возвращаемого массива имеет правильный тип, поэтому вы не заметите проблему. Очевидно, что это вряд ли произойдет в реальной жизни, но это демонстрирует запах кода, который заставляет меня отличать результат - в основном я предпочитаю иметь дело с сильно типизированными коллекциями.


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

foreach (var type in Enums.GetValues<Animal>()) {
    Console.WriteLine(type.ToString());
}

Здесь my Enums.GetValues<T>() возвращает IList<T>, что означает:

  • Не нужно бросать
  • Он фактически возвращает неизменный список, поэтому ему не нужно создавать новую коллекцию каждый раз, в отличие от стандартного Enum.GetValues()

Он также получил общее ограничение, заставляющее T быть типом перечисления, поэтому вы не можете случайно вызвать его с типом non-enum, в отличие от Enum.GetValues()...

+16
источник

Enum.GetValues является вашим другом.

+1
источник

Используйте Enum.GetNames() для прокрутки имен членов вашего перечисления. Используйте Enum.GetValues ​​() для прокрутки значений.

+1
источник

Чтобы сохранить некоторую типизацию в Jon answer, укажите тип явно, и вам не нужно будет делать:

foreach (Animal a in Enum.GetValues(typeof(Animal)) {
    Console.WriteLine(a);
}

Однако это также требует дополнительной осторожности, поскольку объясняется Джоном.

Также обратите внимание, что имена перечислений С# обычно должны быть в единственной форме (Animal, not Animals), если только они не помечены атрибутом [Flags], который позволяет сочетать.

+1
источник

Попробуйте следующее:

    enum animals
    {
        cat,
        dog,
        fish
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        foreach (string myAnimal in Enum.GetNames(typeof(animals)))
        {
            Debug.WriteLine(myAnimal);
        }
    }

Вам нужно выполнить итерацию через Enum.Getnames(typeof (yourEnum)).

Удачи.

+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос