Подтвердить что ты не робот

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 }

Спасибо

4b9b3361

Ответ 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();