Как вы можете перечислить enum
в C #?
Например, следующий код не компилируется:
public enum Suit
{
Spades,
Hearts,
Clubs,
Diamonds
}
public void EnumerateAllSuitsDemoMethod()
{
foreach (Suit suit in Suit)
{
DoSomething(suit);
}
}
И это дает следующую ошибку во время компиляции:
«Костюм» является «типом», но используется как «переменная»
Это терпит неудачу на Suit
ключевом слове, втором.
Ответы:
Примечание : приведение к
(Suit[])
не является строго необходимым, но это делает код быстрее на 0,5 нс .источник
enum.GetValues
. Вы должны использовать отражение в этом случае.enum E {A = 0, B = 0}
.Enum.GetValues
приводит к возвращению двух значений, хотя они одинаковы.E.A == E.B
верно, так что нет различия. Если вы хотите, чтобы отдельные имена, то вы должны искатьEnum.GetNames
.Distinct
расширение Linq (начиная с .NET 3.5), такforeach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }
.var
для типа. Компилятор сделает переменную aObject
вместо enum. Перечислите тип перечисления явно.Мне кажется, что вы действительно хотите распечатать имена каждого перечисления, а не значения. В этом случае,
Enum.GetNames()
кажется, правильный подход.Кстати, увеличение значения не является хорошим способом для перечисления значений перечисления. Вы должны сделать это вместо этого.
Я бы использовал
Enum.GetValues(typeof(Suit))
вместо этого.источник
Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray()
. В этом случае я могу перебирать массив элементовSuits
enum, а не строк.Suits suit in Enum.GetValues(typeof(Suits))
?Я сделал несколько расширений для легкого использования enum. Может быть, кто-то может использовать это ...
Сам перечисление должно быть украшено атрибутом Flags :
источник
Некоторые версии .NET Framework не поддерживают
Enum.GetValues
. Вот хороший обходной путь от Ideas 2.0: Enum.GetValues в Compact Framework :Как и в случае любого кода, в котором используется рефлексия , вы должны предпринять шаги, чтобы убедиться, что он выполняется только один раз и результаты кэшируются.
источник
return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>();
Используйте
Cast<T>
:Вот, пожалуйста
IEnumerable<Suit>
.источник
from
предложении иforeach
деклараторе заголовка.Я думаю, что это более эффективно, чем другие предложения, потому что
GetValues()
не вызывается каждый раз, когда у вас есть цикл. Это также более кратко. И вы получите ошибку во время компиляции, а не исключение времени выполнения, еслиSuit
это не такenum
.EnumLoop
имеет это полностью общее определение:источник
EnumLoop
какой-либо тип, который не является enum, он скомпилируется нормально, но выдает исключение во время выполнения.Вы не попадете
Enum.GetValues()
в Silverlight .Оригинальное сообщение в блоге Эйнара Ингебригтсена :
источник
where T: Enum
Мое решение работает в .NET Compact Framework (3.5) и поддерживает проверку типов во время компиляции :
T valueType = new T()
, я был бы рад увидеть решение.Вызов будет выглядеть так:
источник
T valueType = default(T)
?new()
T
. Кроме того, вам не нужноnew T()
вообще, вы можете выбрать только статические поля и сделать.GetValue(null)
. Смотрите ответ Обри.where T: Enum
Я думаю, что вы можете использовать
источник
источник
Я думаю, что кэширование массива значительно ускорит его. Похоже, вы получаете новый массив (через отражение) каждый раз. Скорее:
По крайней мере, немного быстрее, да?
источник
Три способа:
Enum.GetValues(type)
// Начиная с .NET 1.1, а не в Silverlight или .NET Compact Frameworktype.GetEnumValues()
// Только на .NET 4 и вышеtype.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null))
// Работает вездеЯ не уверен, почему
GetEnumValues
был введен на экземплярах типа. Это не очень читабельно для меня.Наличие вспомогательного класса
Enum<T>
- это то, что наиболее читабельно и запоминается для меня:Теперь вы звоните:
Можно также использовать какое-то кэширование, если производительность имеет значение, но я не ожидаю, что это станет проблемой вообще.
источник
Просто объединив лучшие ответы, я собрал очень простое расширение:
Это чисто, просто и, по словам @ Jeppe-Stig-Nielsen, быстро.
источник
where T: Enum
Есть два способа перебора
Enum
:Первый даст вам значения в виде массива **
object
** s, а второй даст вам значения в виде массива **String
** s.Используйте его в
foreach
цикле, как показано ниже:источник
Я использую ToString (), затем разделяю и разбираю массив spit по флагам.
источник
Я не придерживаюсь мнения, что это лучше или даже хорошо. Я просто заявляю еще одно решение.
Если значения перечисления строго находятся в диапазоне от 0 до n - 1, общая альтернатива:
Если значения перечисления являются смежными, и вы можете предоставить первый и последний элемент перечисления, то:
Но это не строго перечисление, просто зацикливание. Второй способ намного быстрее, чем любой другой подход, хотя ...
источник
Если вам нужна проверка скорости и типа во время сборки и выполнения, этот вспомогательный метод лучше, чем использование LINQ для приведения каждого элемента:
И вы можете использовать его, как показано ниже:
Конечно, вы можете вернуться
IEnumerable<T>
, но здесь вы ничего не купите.источник
where T: Enum
Вот рабочий пример создания опций выбора для DDL :
источник
(В текущем принятом ответе приведен актерский состав, который, по моему мнению, не нужен (хотя я могу ошибаться).)
источник
Этот вопрос появляется в главе 10 « C # Step by Step 2013 »
Автор использует двойной цикл for для перебора пары перечислителей (для создания полной колоды карт):
В этом случае
Suit
иValue
оба перечисления:и
PlayingCard
является объектом карты с определеннымSuit
иValue
:источник
Я знаю, что это немного грязно, но если вы поклонник однострочников, вот один из них:
источник
Что если вы знаете, что тип будет an
enum
, но вы не знаете, какой именно это тип во время компиляции?Метод
getListOfEnum
использует отражение, чтобы взять любой тип перечисления и возвращаетIEnumerable
все значения перечисления.Применение:
источник
Простой и универсальный способ преобразовать перечисление во что-то, с чем вы можете взаимодействовать:
А потом:
источник
Dictionary
Не очень хорошая идея: если у вас естьEnum
какenum E { A = 0, B = 0 }
, то 0 значение добавляется в 2 раза генерацииArgumentException
(вы не можете добавлять то же самоеKey
на черезDictionary
2 и более раз!).Dictionary<,>
из метода с именемToList
? И почему бы не вернутьDictionary<T, string>
?Добавьте метод
public static IEnumerable<T> GetValues<T>()
к вашему классу, например:Позвони и передай свое перечисление. Теперь вы можете перебрать его, используя
foreach
:источник
enum
типы называются «типами перечисления» не потому, что они являются контейнерами, которые «перечисляют» значения (которые они не являются), а потому, что они определяются перечислением возможных значений для переменной этого типа.(На самом деле, это немного сложнее - считается, что типы перечислений имеют «базовый» целочисленный тип, что означает, что каждое значение перечисления соответствует целочисленному значению (обычно это неявное, но может быть указано вручную). C # был разработан таким образом, чтобы вы могли набить любой целое число этого типа в переменную enum, даже если это не «именованное» значение.)
Метод System.Enum.GetNames можно использовать для получения массива строк, которые являются именами значений перечисления, как следует из названия.
РЕДАКТИРОВАТЬ: должен был предложить метод System.Enum.GetValues вместо этого. К сожалению.
источник
GetNames
методе возвращает, действительно, массив строк, но требует ОП перечислителя через значение.Я пробовал много способов и получил результат из этого кода:
Для получения списка int из перечисления используйте следующее. Оно работает!
источник
Также вы можете привязать к общедоступным статическим членам перечисления напрямую с помощью отражения:
источник
Если у тебя есть:
Эта:
Будет выводить:
источник
LINQ Generic Way:
Применение:
источник