Me gustaría saber si es posible obtener atributos de los enum
valores y no de los enum
mismos. Por ejemplo, supongamos que tengo lo siguiente enum
:
using System.ComponentModel; // for DescriptionAttribute
enum FunkyAttributesEnum
{
[Description("Name With Spaces1")]
NameWithoutSpaces1,
[Description("Name With Spaces2")]
NameWithoutSpaces2
}
Lo que quiero es el tipo de enumeración, producir 2 tuplas de valor de cadena de enumeración y su descripción.
El valor fue fácil:
Array values = System.Enum.GetValues(typeof(FunkyAttributesEnum));
foreach (int value in values)
Tuple.Value = Enum.GetName(typeof(FunkyAttributesEnum), value);
Pero, ¿cómo obtengo el valor del atributo de descripción para completar Tuple.Desc
? Puedo pensar en cómo hacerlo si el atributo pertenece a enum
sí mismo, pero no sé cómo obtenerlo del valor de enum
.
c#
reflection
enums
.net-attributes
Alex K
fuente
fuente
DescriptionAttribute
.Respuestas:
Esto debería hacer lo que necesitas.
fuente
Este fragmento de código debería proporcionarle un pequeño método de extensión en cualquier enumeración que le permita recuperar un atributo genérico. Creo que es diferente a la función lambda anterior porque es más simple de usar y ligeramente, solo necesita pasar el tipo genérico.
fuente
IndexOutOfRangeException
?GetCustomAttributes()
luego obtener el primer elemento en lugar de llamarGetCustomAttribute()
?Esta es una implementación genérica que usa una lambda para la selección
Llámalo así:
fuente
FlagsAttribute
). En este caso,enumeration.GetType().GetMember(enumeration.ToString())[0]
fallará.value.GetType().GetField(value.ToString()).GetCustomAttributes(false).OfType<T>().SingleOrDefault()
pero tienes que admitir que tu forma explícita es mejor.He fusionado algunas de las respuestas aquí para crear una solución un poco más extensible. Lo estoy proporcionando en caso de que sea útil para alguien más en el futuro. Publicación original aquí .
Esta solución crea un par de métodos de extensión en Enum. El primero le permite usar la reflexión para recuperar cualquier atributo asociado con su valor. La segunda llamada específicamente recupera
DescriptionAttribute
y devuelve suDescription
valor.Como ejemplo, considere usar el
DescriptionAttribute
atributo deSystem.ComponentModel
Para usar el método de extensión anterior, simplemente debería llamar a lo siguiente:
o
fuente
Además de la respuesta de AdamCrawford , he creado métodos de extensión más especializados que se alimentan de él para obtener la descripción.
por lo tanto, para obtener la descripción, puede usar el método de extensión original como
o simplemente puede llamar al método de extensión aquí como:
Lo que debería hacer que su código sea un poco más legible.
fuente
Un forro fluido ...
Aquí estoy usando el
DisplayAttribute
que contiene las propiedadesName
yDescription
.Ejemplo
Salida
fuente
Aquí hay un código para obtener información de un atributo Display. Utiliza un método genérico para recuperar el atributo. Si no se encuentra el atributo, convierte el valor de enumeración en una cadena con el caso pascal / camel convertido al caso del título (código obtenido aquí )
Y este es el método de extensión para cadenas para convertir a mayúsculas y minúsculas:
fuente
Implementé este método de extensión para obtener la descripción de los valores de enumeración. Funciona para todo tipo de enumeraciones.
fuente
Obtenga el diccionario de enum.
Ahora llama a esto como ...
Método EnumDecription Ext
fuente
Aquí está la versión .NET Core de la respuesta de AdamCrawford, usando System.Reflection.TypeExtensions ;
fuente
Agregar mi solución para Net Framework y NetCore.
Utilicé esto para mi implementación de Net Framework:
Esto no funciona para NetCore, así que lo modifiqué para hacer esto:
Ejemplo de enumeración:
Uso de muestra para cualquier estática agregada:
fuente
Aprovechando algunas de las características más nuevas del lenguaje C #, puede reducir el recuento de líneas:
fuente
En esta respuesta, configuré un cuadro combinado a partir de los atributos de una enumeración que fue genial.
Luego necesitaba codificar el reverso para poder obtener la selección del cuadro y devolver la enumeración en el tipo correcto.
También modifiqué el código para manejar el caso donde faltaba un atributo
Para los beneficios de la próxima persona, aquí está mi solución final
}
fuente
Si
enum
contiene un valor como elEquals
que podría encontrar algunos errores usando algunas extensiones en muchas respuestas aquí. Esto se debe a que normalmente se supone quetypeof(YourEnum).GetMember(YourEnum.Value)
devolvería solo un valor, que es elMemberInfo
de suenum
. Aquí hay una versión un poco más segura de la respuesta de Adam Crawford .fuente
Este método de extensión obtendrá una representación de cadena de un valor enum utilizando su XmlEnumAttribute. Si no hay XmlEnumAttribute presente, recurre a enum.ToString ().
fuente
Y si quieres la lista completa de nombres, puedes hacer algo como
fuente
Chicos, si ayuda, compartiré con ustedes mi solución: Definición del atributo personalizado:
Ahora porque lo necesitaba dentro de la definición HtmlHelper de la extensión HtmlHelper:
Espero eso ayude
fuente
Ahora producirá un error en este caso 1 "Igual"
así que si es el mismo nombre de enumeración de retorno en lugar de mostrar el nombre porque enumMember.GetCustomAttribute () se vuelve nulo si el nombre de visualización y el nombre de enumeración son iguales .....
fuente
Alternativamente, puede hacer lo siguiente:
fuente
Así es como lo resolví sin usar ayudantes personalizados o extensiones con .NET core 3.1.
Clase
Maquinilla de afeitar
fuente
El rendimiento importa
Si desea un mejor rendimiento, este es el camino a seguir:
¿Por qué tiene esto un mejor rendimiento?
Debido a que todos los métodos incorporados usan código muy similar a este, excepto que también ejecutan un montón de otro código que no nos importa . El código Enum de C # es bastante horrible en general.
El código anterior se ha simplificado y simplificado para que solo contenga los bits que nos interesan.
¿Por qué el código incorporado es lento?
Primero con respecto a Enum.ToString () -vs- Enum.GetName (..)
Siempre usa este último. (O mejor aún, tampoco, como se verá más adelante).
ToString () usa este último internamente, pero de nuevo, también hace un montón de otras cosas que no queremos, por ejemplo, intenta combinar banderas, imprimir números, etc. Solo nos interesan las constantes definidas dentro de la enumeración.
Enum.GetName a su vez obtiene todos los campos, crea una matriz de cadenas para todos los nombres, usa el ToUInt64 anterior en todos sus RawConstantValues para crear una matriz UInt64 de todos los valores, clasifica ambas matrices de acuerdo con el valor UInt64 y finalmente obtiene el nombre de la matriz de nombres haciendo una BinarySearch en la matriz UInt64 para encontrar el índice del valor que queríamos.
... y luego tiramos los campos y las matrices ordenadas usan ese nombre para encontrar el campo nuevamente.
Una palabra: "¡Uf!"
fuente
Alternativamente, puede hacer lo siguiente:
Y obtenga la descripción con lo siguiente:
En mi opinión, esta es una forma más eficiente de hacer lo que desea lograr, ya que no se necesita reflexión.
fuente
También puede definir un valor de enumeración como
Name_Without_Spaces
, y cuando desee una descripción, useName_Without_Spaces.ToString().Replace('_', ' ')
para reemplazar los guiones bajos por espacios.fuente