Как перечислить все значения перечисления (enum) в C#?
Использование метода Enum.GetValues
В C# для перечисления всех значений перечисления используется статический метод Enum.GetValues(). Этот метод возвращает массив всех констант указанного перечисления в порядке их объявления. Он работает с любым перечислением, включая те, которые имеют атрибуты (например, [Flags]).
Вот как исправить ваш пример:
public enum DaysOfWeek
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
// Получаем массив всех значений перечисления
DaysOfWeek[] allDays = (DaysOfWeek[])Enum.GetValues(typeof(DaysOfWeek));
// Перебираем массив
foreach (DaysOfWeek day in allDays)
{
Console.WriteLine(day); // Выведет: Monday, Tuesday, ...
}
Важные детали
- Приведение типа:
Enum.GetValues()возвращает массив типаArray, поэтому требуется явное приведение к массиву вашего перечисления ((DaysOfWeek[])). - Использование var: Можно упростить код, используя
varи вызовCast<T>()из LINQ:
using System.Linq;
var allDays = Enum.GetValues(typeof(DaysOfWeek)).Cast<DaysOfWeek>();
foreach (var day in allDays)
{
Console.WriteLine(day);
}
Работа с именами и числовыми значениями
Если вам нужно получить строковые имена констант, используйте Enum.GetNames():
string[] dayNames = Enum.GetNames(typeof(DaysOfWeek));
foreach (string name in dayNames)
{
Console.WriteLine(name); // "Monday", "Tuesday", ...
}
А если нужны числовые значения (int), можно привести каждый элемент:
foreach (int value in Enum.GetValues(typeof(DaysOfWeek)))
{
Console.WriteLine($"{(DaysOfWeek)value} = {value}");
// Выведет: Monday = 0, Tuesday = 1, ...
}
Обобщённый метод (Generic)
Для удобства можно написать вспомогательный метод:
public static IEnumerable<T> GetAllEnumValues<T>() where T : Enum
{
return Enum.GetValues(typeof(T)).Cast<T>();
}
// Использование:
var days = GetAllEnumValues<DaysOfWeek>();
foreach (var day in days)
{
Console.WriteLine(day);
}
Производительность
Метод Enum.GetValues() кэширует результаты внутри .NET, поэтому его многократный вызов не создаёт новых массивов каждый раз. Это эффективно даже для больших перечислений.
Таким образом, правильный способ — использовать Enum.GetValues(typeof(YourEnum)). Это стандартный, документированный и производительный подход, который работает во всех версиях .NET (включая .NET Framework, .NET Core и .NET 5+).
Альтернативный подход: рефлексия и кэширование
Хотя Enum.GetValues() — оптимальное решение, в некоторых случаях (например, при работе с динамическими типами или в высоконагруженных системах) можно использовать рефлексию с кэшированием результатов:
using System.Reflection;
public static class EnumHelper
{
private static readonly Dictionary<Type, object[]> _cache = new();
public static T[] GetValues<T>() where T : Enum
{
var type = typeof(T);
if (!_cache.TryGetValue(type, out var values))
{
values = type.GetFields(BindingFlags.Public | BindingFlags.Static)
.Select(f => f.GetValue(null))
.ToArray();
_cache[type] = values;
}
return (T[])values;
}
}
// Использование:
var days = EnumHelper.GetValues<DaysOfWeek>();
foreach (var day in days) Console.WriteLine(day);
Этот подход полезен, если вам нужно получить значения перечисления, но вы не доверяете встроенному методу (например, при работе с очень старыми версиями .NET). Однако в 99% случаев используйте Enum.GetValues() — он проще, быстрее и лучше поддерживается.
Также стоит отметить, что в .NET 5+ появился обобщённый вариант Enum.GetValues<TEnum>(), который возвращает TEnum[] без необходимости приведения:
// .NET 5+
DaysOfWeek[] days = Enum.GetValues<DaysOfWeek>();