Функция C #, которая принимает элемент Enum и возвращает значение enum (не индекс) - PullRequest
4 голосов
/ 27 марта 2009

говорят, что у меня есть следующие декларации:

public enum Complexity { Low = 0, Normal = 1, Medium = 2,  High = 3 }
public enum Priority { Normal = 1, Medium = 2,  High = 3, Urgent = 4 }

и я хочу закодировать его, чтобы я мог получить значение перечисления (а не индекс, как я упоминал ранее):

//should store the value of the Complexity enum member Normal, which is 1
int complexityValueToStore = EnumHelper.GetEnumMemberValue(Complexity.Normal); 
//should store the value 4
int priorityValueToStore = EnumHelper.GetEnumMemberValue(Priority.Urgent); 

Как должна выглядеть эта многоразовая функция?

ТИА! -ren

Ответы [ 6 ]

15 голосов
/ 27 марта 2009

Исправленный ответ (после уточнения вопроса)

Нет, нет ничего чище, чем актеры. Он более информативен, чем вызов метода, дешевле, короче и т. Д. Он настолько слаб, насколько вы могли бы надеяться.

Обратите внимание, что если вы хотите написать общий метод для преобразования, вам также нужно указать, во что его преобразовать: перечисление может основываться, например, на byte или long. Вставляя приведение, вы явно говорите, во что хотите преобразовать его, и он просто делает это.

Оригинальный ответ

Что именно вы подразумеваете под "индексом"? Вы имеете в виду числовое значение? Просто приведите к int. Если вы имеете в виду «позиция в enum», вам нужно убедиться, что значения находятся в числовом порядке (как это дает Enum.GetValues, а не порядок объявления), а затем выполните:

public static int GetEnumMemberIndex<T>(T element)
    where T : struct
{
    T[] values = (T[]) Enum.GetValues(typeof(T));
    return Array.IndexOf(values, element);
}
8 голосов
/ 27 марта 2009

Целочисленное значение перечисления можно найти, выполнив приведение:

int complexityValueToStore = (int)Complexity.Normal;
4 голосов
/ 09 февраля 2010

Самый общий способ, который я знаю, это прочитать поле value__ с помощью отражения. Этот подход не делает никаких предположений о базовом типе перечисления, поэтому он будет работать с перечислениями, которые не основаны на Int32.

public static object GetValue(Enum e)
{
    return e.GetType().GetField("value__").GetValue(e);
}

Debug.Assert(Equals(GetValue(DayOfWeek.Wednesday), 3));                //Int32
Debug.Assert(Equals(GetValue(AceFlags.InheritOnly), (byte) 8));        //Byte
Debug.Assert(Equals(GetValue(IOControlCode.ReceiveAll), 2550136833L)); //Int64

Примечание. Я проверял это только с помощью компилятора Microsoft C #. Обидно, что, кажется, нет встроенного способа сделать это.

2 голосов
/ 27 марта 2009

Я понимаю, что это не то, что вы спросили, но это то, что вы могли бы оценить.

Я обнаружил, что вы можете найти целочисленное значение перечисления без приведения, если вы знаете, каково минимальное значение перечисления:

public enum Complexity { Low = 0, Normal = 1, Medium = 2,  High = 3 }

int valueOfHigh = Complexity.High - Complexity.Low;

Это не будет работать с Приоритетом, если вы не добавили минимальное значение 0 или не добавили 1 обратно:

public enum Priority { Normal = 1, Medium = 2,  High = 3, Urgent = 4 }

int valueOfUrgent = Priority.Urgent - Priority.Normal + 1;

Я считаю эту технику намного более эстетически привлекательной, чем приведение к int.

Я не совсем уверен, что произойдет, если у вас есть перечисление, основанное на байтах или длинных - я подозреваю, что вы получите байтовые или длинные значения разностей.

0 голосов
/ 08 февраля 2014

Это самый простой способ решения вашей проблемы:

public static void GetEnumMemberValue<T>(T enumItem) where T : struct 
{
    return (int) Enum.Parse(typeof(T), enumItem.ToString());
}

Это работает для меня.

0 голосов
/ 27 марта 2009

Если вы хотите значение, вы можете просто привести enum к int. Это установит сложностьValueToStore == 1 и priorityValueToStore == 4.

Если вы хотите получить индекс (то есть: Priority.Urgent == 3), вы можете использовать Enum.GetValues ​​, а затем просто найти индекс вашего текущего перечисления в этом списке. Однако порядок перечисления в возвращаемом списке может отличаться от вашего кода.

Однако, второй вариант в первую очередь побеждает цель Enum - вы пытаетесь иметь дискретные значения вместо списков и индексов. Я бы переосмыслил твои нужды, если ты этого хочешь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...