values name getnames getname example enum c# vb.net reflection enums

c# - name - Recuperar valor de enumeración basado en el valor de nombre XmlEnumAttribute



enum getnames c# example (5)

@Dean, @Jason y @Camron, gracias por sus soluciones. Sus soluciones me ayudaron a resolver mi problema, donde, dado un nombre XmlEnumAttribute, se necesitaba el valor de enumeración real.

Mi variante se menciona here .

También lo incluyo aquí como lo pidió uno de nuestros moderadores:

El problema real fue cómo obtener el Item10, cuando se le asignó un valor de 10. Siguiendo el ejemplo de la solución citada por nuestros amigos mencionados anteriormente, se me ocurrió el siguiente método, que al pasar un valor contenido en XmlEnumAttribute, devolvería la enumeración valor:

private static T GetEnumValueFromXmlAttrName<T>(string attribVal) { T val = default(T); if (typeof(T).BaseType.FullName.Equals("System.Enum")) { FieldInfo[] fields = typeof(T).GetFields(); foreach (FieldInfo field in fields) { object[] attribs = field.GetCustomAttributes(typeof(XmlEnumAttribute), false); foreach (object attr in attribs) { if ((attr as XmlEnumAttribute).Name.Equals(attribVal)) { val = (T)field.GetValue(null); return val; } } } } else throw new Exception("The supplied type is not an Enum."); return val; }

Necesito una función genérica para recuperar el nombre o valor de una enumeración basada en la propiedad "Nombre" de XmlEnumAttribute de la enumeración. Por ejemplo tengo la siguiente enumeración definida:

Public Enum Currency <XmlEnum("00")> CDN = 1 <XmlEnum("01")> USA= 2 <XmlEnum("02")> EUR= 3 <XmlEnum("03")> JPN= 4 End Enum

El primer valor de enumeración de moneda es 1; el nombre de la enumeración es "CDN"; y el valor de la propiedad XMLEnumAttribute Name es "00".

Si tengo el valor enum, puedo recuperar el valor "Nombre" de XmlEnumAttribute usando la siguiente función genérica:

Public Function GetXmlAttrNameFromEnumValue(Of T)(ByVal pEnumVal As T) As String Dim type As Type = pEnumVal.GetType Dim info As FieldInfo = type.GetField([Enum].GetName(GetType(T), pEnumVal)) Dim att As XmlEnumAttribute = CType(info.GetCustomAttributes(GetType(XmlEnumAttribute), False)(0), XmlEnumAttribute) ''If there is an xmlattribute defined, return the name Return att.Name End Function

Entonces, usando la función anterior, puedo especificar el tipo de enumeración de Moneda, pasar un valor de 1 y el valor de retorno será "00".

Lo que necesito es una función para realizar si ocurre lo contrario. Si tengo el valor del nombre del atributo XmlEnumAttribute "00", necesito una función para devolver una enumeración de moneda con un valor de 1. Tan útil sería una función que devolvería el nombre de enumeración "CDN". Entonces podría simplemente analizar esto para obtener el valor de enumeración.

Cualquier ayuda sería apreciada.


Aquí hay una variación que genera un diccionario desde la enumeración, lo que le permite potencialmente almacenar en caché la parte de reflexión en caso de que necesite usarlo mucho.

/// <summary> /// Generates a dictionary allowing you to get the csharp enum value /// from the string value in the matching XmlEnumAttribute. /// You need this to be able to dynamically set entries from a xsd:enumeration /// when you''ve used xsd.exe to generate a .cs from the xsd. /// https://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx /// </summary> /// <typeparam name="T">The xml enum type you want the mapping for</typeparam> /// <returns>Mapping dictionary from attribute values (key) to the actual enum values</returns> /// <exception cref="System.ArgumentException">T must be an enum</exception> private static Dictionary<string, T> GetEnumMap<T>() where T : struct, IConvertible { if (!typeof(T).IsEnum) { throw new ArgumentException("T must be an enum"); } var members = typeof(T).GetMembers(); var map = new Dictionary<string, T>(); foreach (var member in members) { var enumAttrib = member.GetCustomAttributes(typeof(XmlEnumAttribute), false).FirstOrDefault() as XmlEnumAttribute; if (enumAttrib == null) { continue; } var xmlEnumValue = enumAttrib.Name; var enumVal = ((FieldInfo)member).GetRawConstantValue(); map.Add(xmlEnumValue, (T)enumVal); } return map; }

uso:

var map = GetEnumMap<Currency>(); return map["02"]; // returns Currency.EUR


Hago algo similar con los atributos personalizados y utilizo este método para obtener el EnumValue basado en el Valor del atributo. GetStringValue es mi método personalizado, similar a su ejemplo anterior.

public static class Enums { public static T GetCode<T>(string value) { foreach (object o in System.Enum.GetValues(typeof(T))) { if (((Enum)o).GetStringValue().Equals(value, StringComparison.OrdinalIgnoreCase)) return (T)o; } throw new ArgumentException("No code exists for type " + typeof(T).ToString() + " corresponding to value of " + value); } }

Para todo el proceso, uso esta publicación y las respuestas: ¿ Extender Enums, Overkill?

Lo siento, esto está en C #, me di cuenta de que estabas usando VB.NET arriba.


Ligeramente modificado de: http://www.wackylabs.net/2006/06/getting-the-xmlenumattribute-value-for-an-enum-field/

public static string ToString2 (this Enum e) { // Get the Type of the enum Type t = e.GetType (); // Get the FieldInfo for the member field with the enums name FieldInfo info = t.GetField (e.ToString ("G")); // Check to see if the XmlEnumAttribute is defined on this field if (!info.IsDefined (typeof (XmlEnumAttribute), false)) { // If no XmlEnumAttribute then return the string version of the enum. return e.ToString ("G"); } // Get the XmlEnumAttribute object[] o = info.GetCustomAttributes (typeof (XmlEnumAttribute), false); XmlEnumAttribute att = (XmlEnumAttribute)o[0]; return att.Name; }


Un requisito para resolver este mismo problema exacto me llevó a esta pregunta y respuesta. A medida que me desarrollo en VB.NET, reescribí la solución de CkH en VB y la modifiqué para usar su función GetXmlAttrNameFromEnumValue .

Public Shared Function GetCode(Of T)(ByVal value As String) As T For Each o As Object In System.Enum.GetValues(GetType(T)) Dim enumValue As T = CType(o, T) If GetXmlAttrNameFromEnumValue(Of T)(enumValue).Equals(value, StringComparison.OrdinalIgnoreCase) Then Return CType(o, T) End If Next Throw New ArgumentException("No code exists for type " + GetType(T).ToString() + " corresponding to value of " + value) End Function

Versión C #:

public static string GetXmlAttrNameFromEnumValue<T>(T pEnumVal) { // http://.com/q/3047125/194717 Type type = pEnumVal.GetType(); FieldInfo info = type.GetField(Enum.GetName(typeof(T), pEnumVal)); XmlEnumAttribute att = (XmlEnumAttribute)info.GetCustomAttributes(typeof(XmlEnumAttribute), false)[0]; //If there is an xmlattribute defined, return the name return att.Name; } public static T GetCode<T>(string value) { // http://.com/a/3073272/194717 foreach (object o in System.Enum.GetValues(typeof(T))) { T enumValue = (T)o; if (GetXmlAttrNameFromEnumValue<T>(enumValue).Equals(value, StringComparison.OrdinalIgnoreCase)) { return (T)o; } } throw new ArgumentException("No XmlEnumAttribute code exists for type " + typeof(T).ToString() + " corresponding to value of " + value); }