Как перебрать все значения перечисления (enum) в C#?
Использование Enum.GetValues для перебора значений
В C# для перебора всех значений перечисления используется статический метод Enum.GetValues. Этот метод возвращает массив всех констант указанного перечисления в том порядке, в котором они объявлены. Он работает для любого перечисления, независимо от того, заданы ли значения явно или нет, и даже если они не являются последовательными.
Вот как правильно решить вашу задачу:
using System;
enum DaysOfWeek
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
class Program
{
static void Main()
{
// Получаем массив всех значений перечисления
DaysOfWeek[] allDays = (DaysOfWeek[])Enum.GetValues(typeof(DaysOfWeek));
// Перебираем все значения
foreach (DaysOfWeek day in allDays)
{
Console.WriteLine(day);
}
}
}
Вывод:
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
Более современный подход с generics (C# 7.3+)
Начиная с C# 7.3, вы можете использовать обобщённую версию метода Enum.GetValues<T>(), которая избавляет от необходимости явного приведения типов:
foreach (DaysOfWeek day in Enum.GetValues<DaysOfWeek>())
{
Console.WriteLine(day);
}
Этот вариант короче и безопаснее с точки зрения типов.
Получение имён вместо значений
Если вам нужны строковые имена констант (например, для отображения в UI), используйте Enum.GetNames:
string[] dayNames = Enum.GetNames(typeof(DaysOfWeek));
foreach (string name in dayNames)
{
Console.WriteLine(name);
}
Практические примеры использования
- Заполнение выпадающего списка в WinForms/WPF:
comboBox1.DataSource = Enum.GetValues(typeof(DaysOfWeek)); - Проверка, является ли значение частью перечисления:
if (Enum.IsDefined(typeof(DaysOfWeek), "Monday")) Console.WriteLine("Monday is a valid day"); - Преобразование строки в значение enum:
DaysOfWeek day = (DaysOfWeek)Enum.Parse(typeof(DaysOfWeek), "Friday");
Важные замечания
- Производительность: Метод
GetValuesкэширует результаты внутри .NET, поэтому при многократном вызове для одного и того же типа перечисления он работает быстро. - Enum с флагами (Flags): Если ваше перечисление помечено атрибутом
[Flags],GetValuesвернёт только определённые именованные комбинации, а не все возможные битовые комбинации. Для перебора всех возможных флагов используйте битовые операции. - Пустые перечисления: Метод вернёт пустой массив, если перечисление не содержит ни одной константы.
Этот подход универсален: он работает для любого перечисления, даже если оно определено во внешней библиотеке, и не требует ручного изменения кода при добавлении новых констант.
<<Альтернативный подход: использование рефлексии и LINQ
Хотя Enum.GetValues — это стандартный и рекомендуемый способ, иногда требуется более гибкий подход. Например, если вы хотите отфильтровать значения по какому-либо признаку или получить дополнительные метаданные из атрибутов.
Вот пример с использованием рефлексии и LINQ:
using System;
using System.Linq;
using System.Reflection;
enum Status
{
[System.ComponentModel.Description("Активен")]
Active,
[System.ComponentModel.Description("Неактивен")]
Inactive,
[System.ComponentModel.Description("В обработке")]
Pending
}
class Program
{
static void Main()
{
var values = Enum.GetValues(typeof(Status))
.Cast<Status>()
.Where(s => s != Status.Pending) // исключаем "Pending"
.ToList();
foreach (var status in values)
{
// Получаем Description через рефлексию
var field = typeof(Status).GetField(status.ToString());
var attr = field.GetCustomAttribute<System.ComponentModel.DescriptionAttribute>();
string description = attr?.Description ?? status.ToString();
Console.WriteLine($"{status}: {description}");
}
}
}
Этот подход полезен, когда вам нужно работать с атрибутами, фильтровать значения или выполнять дополнительные преобразования. Однако помните, что рефлексия работает медленнее, поэтому для простого перебора лучше использовать Enum.GetValues.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги
Эволюция мема: как нейросети породили новых цифровых зверей и почему все смеются с Бомбардиро Крокодило