Я хотел бы знать, возможно ли получить атрибуты enum
значений, а не enum
самого? Например, предположим, у меня есть следующее enum
:
using System.ComponentModel; // for DescriptionAttribute
enum FunkyAttributesEnum
{
[Description("Name With Spaces1")]
NameWithoutSpaces1,
[Description("Name With Spaces2")]
NameWithoutSpaces2
}
То, что я хочу, это дать тип enum, произвести 2 кортежа значения строки enum и его описание.
Значение было легко:
Array values = System.Enum.GetValues(typeof(FunkyAttributesEnum));
foreach (int value in values)
Tuple.Value = Enum.GetName(typeof(FunkyAttributesEnum), value);
Но как мне получить значение атрибута description для заполнения Tuple.Desc
? Я могу думать о том, как это сделать, если Атрибут принадлежит самому enum
себе, но я не знаю, как получить его из значения enum
.
c#
reflection
enums
.net-attributes
Алекс К
источник
источник
DescriptionAttribute
.Ответы:
Это должно делать то, что вам нужно.
источник
Этот фрагмент кода должен дать вам хороший метод расширения для любого перечисления, который позволяет вам получить универсальный атрибут. Я считаю, что она отличается от лямбда-функции, описанной выше, потому что она проще в использовании и немного - вам нужно только передать универсальный тип.
источник
IndexOutOfRangeException
?GetCustomAttributes()
тогда получить первый элемент вместо звонкаGetCustomAttribute()
?Это общая реализация, использующая лямбда для выбора
Назовите это так:
источник
FlagsAttribute
). В этом случаеenumeration.GetType().GetMember(enumeration.ToString())[0]
не получится.value.GetType().GetField(value.ToString()).GetCustomAttributes(false).OfType<T>().SingleOrDefault()
но лучше признать, что ваш явный путь лучше.Я объединил пару ответов здесь, чтобы создать немного более расширяемое решение. Я предоставляю это на всякий случай, если это пригодится кому-то еще в будущем. Оригинальное размещение здесь .
Это решение создает пару методов расширения в Enum. Первый позволяет использовать отражение, чтобы получить любой атрибут, связанный с вашим значением. Второй специально вызывает, извлекает
DescriptionAttribute
и возвращает егоDescription
значение.В качестве примера рассмотрим использование
DescriptionAttribute
атрибута изSystem.ComponentModel
Чтобы использовать вышеупомянутый метод расширения, вы бы просто вызвали следующее:
или
источник
В дополнение к ответу AdamCrawford я также создал более специализированные методы расширения, которые используют его для получения описания.
следовательно, чтобы получить описание, вы можете использовать оригинальный метод расширения как
или вы можете просто вызвать метод расширения здесь как:
Который, надеюсь, должен сделать ваш код немного более читабельным.
источник
Свободный один лайнер ...
Здесь я использую,
DisplayAttribute
который содержитName
иDescription
свойства и.пример
Вывод
источник
Вот код для получения информации из атрибута Display. Он использует универсальный метод для получения атрибута. Если атрибут не найден, он преобразует значение перечисления в строку с регистром паскаля / верблюда, преобразованным в регистр заголовка (код, полученный здесь )
И это метод расширения строк для преобразования в регистр заголовков:
источник
Я реализовал этот метод расширения, чтобы получить описание из значений перечисления. Это работает для всех видов перечислений.
источник
Получить словарь из enum.
Теперь назовите это как ...
EnumDecription Ext Метод
источник
Вот версия .NET Core ответа AdamCrawford с использованием System.Reflection.TypeExtensions ;
источник
Добавление моего решения для Net Framework и NetCore.
Я использовал это для моей реализации Net Framework:
Это не работает для NetCore, поэтому я изменил это, чтобы сделать это:
Пример перечисления:
Пример использования для каждого из добавленных статических:
источник
Используя некоторые из новых возможностей языка C #, вы можете уменьшить количество строк:
источник
Я этот ответ, чтобы настроить поле со списком из перечисленных атрибутов, что было здорово.
Затем мне нужно было написать обратное, чтобы я мог получить выборку из коробки и вернуть перечисление в правильном типе.
Я также изменил код для обработки случая, когда атрибут отсутствовал
Для пользы следующего человека, вот мое окончательное решение
}
источник
Если ваш
enum
содержит такое значение, какEquals
вы можете столкнуться с несколькими ошибками, используя некоторые расширения во многих ответах здесь. Это потому, что обычно предполагается,typeof(YourEnum).GetMember(YourEnum.Value)
что вернет только одно значение, которое являетсяMemberInfo
вашимenum
. Вот немного более безопасная версия ответа Адама Кроуфорда .источник
Этот метод расширения получит строковое представление значения перечисления, используя его XmlEnumAttribute. Если XmlEnumAttribute отсутствует, он возвращается к enum.ToString ().
источник
И если вы хотите полный список имен, вы можете сделать что-то вроде
источник
Ребята, если это поможет, я поделюсь с вами своим решением: Определение атрибута Custom:
Теперь, потому что я нуждался в этом в определении HtmlHelper расширения HtmlHelper:
Надеюсь, поможет
источник
Теперь это будет выдавать ошибку в этом случае 1 "равно"
так что если это одно и то же имя, возвращаемое перечисление, а не отображаемое имя, потому что enumMember.GetCustomAttribute () получает значение NULL, если отображаемое имя и имя перечисления совпадают .....
источник
В качестве альтернативы вы можете сделать следующее:
источник
Вот как я решил это без использования пользовательских помощников или расширений с .NET core 3.1.
Учебный класс
бритва
источник
Вопросы производительности
Если вы хотите лучшую производительность, вот путь:
Почему это имеет лучшую производительность?
Поскольку все встроенные методы используют код, очень похожий на этот, за исключением того, что они также запускают кучу другого кода, который нас не волнует . Код Enum в C # вообще ужасен.
Приведенный выше код был Linq-ified и оптимизирован, поэтому он содержит только те биты, которые нам нужны.
Почему встроенный код работает медленно?
Сначала о Enum.ToString () -vs- Enum.GetName (..)
Всегда используйте последнее. (Или, еще лучше, ни то, ни другое, как станет ясно ниже.)
ToString () использует последнее внутренне, но, опять же, также делает кучу других вещей, которые нам не нужны, например, пытается объединить флаги, распечатать числа и т. Д. Нас интересуют только константы, определенные внутри перечисления.
Enum.GetName, в свою очередь, получает все поля, создает строковый массив для всех имен, использует вышеупомянутый ToUInt64 на всех их RawConstantValues для создания массива всех значений UInt64, сортирует оба массива в соответствии со значением UInt64 и, наконец, получает имя из массив имен, выполнив BinarySearch в массиве UInt64, чтобы найти индекс нужного нам значения.
... а затем мы выбрасываем поля и отсортированные массивы, используя это имя, чтобы снова найти поле.
Одно слово: "Тьфу!"
источник
В качестве альтернативы вы можете сделать следующее:
И получите описание со следующим:
На мой взгляд, это более эффективный способ сделать то, что вы хотите достичь, так как не требуется никакого отражения ..
источник
Вы также можете определить значение перечисления, например
Name_Without_Spaces
, и когда вы хотите, чтобы описание использовалосьName_Without_Spaces.ToString().Replace('_', ' ')
для замены подчеркивания пробелами.источник