Enum.GetValues () Тип возврата
Я прочитал документацию, в которой говорится, что "заданный тип перечисления, метод GetValues () System.Enum вернет массив заданного базового типа enum, т.е. int, byte и т.д.
Однако я использую метод GetValues, и все, что я получаю, это массив типа Enums. Я что-то пропустил?
public enum Response
{
Yes = 1,
No = 2,
Maybe = 3
}
foreach (var value in Enum.GetValues(typeof(Response)))
{
var type = value.GetType(); // type is always of type Enum not of the enum base type
}
Спасибо
Ответы
Ответ 1
Вам нужно передать результат фактическому типу массива, который вы хотите
(Response[])Enum.GetValues(typeof(Response))
поскольку GetValues не строго типизирован
EDIT: просто перечитайте ответ. Вам нужно явно указать каждое значение перечисления на базовый тип, поскольку GetValues возвращает массив фактического типа перечисления, а не базового типа. Enum.GetUnderlyingType может помочь с этим.
Ответ 2
Если вы используете NET 3.5 (т.е. имеете LINQ), вы можете:
var responses = Enum.GetValues(typeof(Response)).Cast<Response>();
Ответ 3
Пожалуйста, обратитесь к документации, которую вы упомянули. документация MSDN на Enum.GetValues
не упоминает ничего подобного (цитата с этой страницы):
Возвращаемое значение
Тип: System.Array
Массив значения констант в enumType. Элементы массива отсортированы по двоичным значениям константы перечисления.
Ответ 4
Лично я создал отдельный метод в моем проекте Utils, который я включил в мои другие проекты. Здесь код, который я использую:
public static class EnumUtil
{
public static IEnumerable<TEnum> GetAllValues<TEnum>()
where TEnum : struct, IConvertible, IComparable, IFormattable
{
return Enum.GetValues(typeof(TEnum)).Cast<TEnum>();
}
}
И я называю это следующим образом:
var enumValues = EnumUtil.GetAllValues<Response>();
Ответ 5
Как Roger, упомянутый в комментарии, было бы неплохо, если бы была общая реализация Enum.GetValues<MyEnum>()
, но ее не было.
Эта проблема также раздражала меня, поэтому я создал библиотеку в С++/CLI, которая имеет общие реализации всех статических методов класса Enum
(а также множество других общих методов работы с перечислениями).
Библиотека написана на С++/CLI, потому что С# не поддерживает ограничение общего типа System.Enum. С++/CLI (и CLR) поддерживают ограничение с помощью System.Enum и С#/VB.NET не имеет проблем с пониманием вызовов метода, который имеет это ограничение.
В случае вашего примера вы должны использовать Enums.GetValues<MyEnumType>()
, который передаст вам массив MyEnumType
без необходимости кастования. Хотя С# и VB.Net не поддерживают определение ограничения enum, у них нет проблем с потреблением метода/класса с таким ограничением, а intellisense/компилятор отлично справляется с этим.
Ответ 6
Как и Joel Answer, но сделал несколько иначе:
public static class Enums<T>
where T : struct, IComparable, IFormattable, IConvertible
{
static Enums()
{
if (!typeof(T).IsEnum)
throw new ArgumentException("Type T must be an Enum type");
}
public static IEnumerable<T> GetValues()
{
var result = ((T[])Enum.GetValues(typeof(T)).ToList()
return result;
}
}
Использование:
IEnumerable<System.Drawing.FontStyle> styles = Enums<System.Drawing.FontStyle>.GetValues();