Obtención de valor enum a través de la reflexión

Tengo un simple enum

public enum TestEnum { TestOne = 3, TestTwo = 4 } var testing = TestEnum.TestOne; 

Y quiero recuperar su valor (3) a través de la reflexión. ¿Alguna idea sobre cómo hacer esto?

Gran pregunta Mat.

El escenario de la pregunta es este:

Tiene algún tipo de enumeración desconocido y algún valor desconocido de ese tipo y desea obtener el valor numérico subyacente de ese valor desconocido.

Esta es la forma en una línea de hacer esto usando la reflexión:

 object underlyingValue = Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType())); 

Si resulta que el valor es TestEnum.TestTwo , entonces value.GetType() sería igual a typeof(TestEnum) , Enum.GetUnderlyingType(value.GetType()) sería igual a typeof(int) y el valor sería 3 (en el recuadro; vea http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx para obtener más detalles sobre el boxeo y los valores de unboxing).

¿Por qué uno necesitaría escribir tal código? En mi caso, tengo una rutina que copia los valores de un modelo de vista a un modelo. Lo uso en todos mis controladores en un proyecto MVC de ASP.NET como parte de una architecture muy limpia y elegante para escribir controladores que no tienen los problemas de seguridad que tienen los controladores generados por las plantillas de Microsoft.

El modelo lo genera Entity Framework a partir de la base de datos y contiene un campo de tipo int. El modelo de vista tiene un campo de algún tipo de enumeración, llamémoslo RecordStatus, que he definido en otra parte de mi proyecto. Decidí apoyar completamente las enumeraciones en mi marco. Pero ahora hay una discrepancia entre el tipo de campo en el modelo y el tipo del campo correspondiente en el modelo de vista. Mi código lo detecta y convierte la enumeración en un int utilizando el código similar al de una línea anterior.

Puede utilizar los ayudantes System.Enum:

 System.Type enumType = typeof(TestEnum); System.Type enumUnderlyingType = System.Enum.GetUnderlyingType(enumType); System.Array enumValues = System.Enum.GetValues(enumType); for (int i=0; i < enumValues.Length; i++) { // Retrieve the value of the ith enum item. object value = enumValues.GetValue(i); // Convert the value to its underlying type (int, byte, long, ...) object underlyingValue = System.Convert.ChangeType(value, enumUnderlyingType); System.Console.WriteLine(underlyingValue); } 

Salidas

3
4

Código completo: cómo obtener valores enumerados con reflexión en C #

 MemberInfo[] memberInfos = typeof(MyEnum).GetMembers(BindingFlags.Public | BindingFlags.Static); string alerta = ""; for (int i = 0; i < memberInfos.Length; i++) { alerta += memberInfos[i].Name + " - "; alerta += memberInfos[i].GetType().Name + "\n"; } 

¿Por qué necesitas reflexión?

 int value = (int)TestEnum.TestOne; 

Intenta lo siguiente:

 System.Array enumValues = System.Enum.GetValues(typeof(MyEnum)); Type underlyingType = System.Enum.GetUnderlyingType(MyEnum); foreach (object enumValue in enumValues) System.Console.WriteLine(String.Format("{0}",Convert.ChangeType(enumValue ,underlyingType))); 

Para su requerimiento es tan simple como la gente ya lo señaló. Simplemente convierta el objeto enum a int y obtendrá el valor numérico de la enumeración.

 int value = (int) TestEnum.TestOne; 

Sin embargo, si es necesario mezclar los valores de enumeración con | (OR en modo bit) por ejemplo

 var value = TestEnum.TestOne | TestEnum.TestTwo; 

y desea obtener las opciones que representa el valor combinado, a continuación le indicamos cómo podría hacerlo (nota: esto es para las enumeraciones representadas por los valores int destinados a aprovechar las operaciones a nivel de bits):

Primero, obtenga las opciones de enumeración junto con sus valores en un diccionario.

 var all_options_dic = typeof(TestEnum).GetEnumValues().Cast().ToDictionary(k=>k.ToString(), v=>(int) v); 

Filtra el diccionario para devolver solo las opciones mezcladas.

 var filtered = all_options_dic.Where(x => (x.Value & (int) options) != 0).ToDictionary(k=>k.Key, v=>v.Value); 

Haz cualquier lógica con tus opciones. Ej. imprimiéndolos, convirtiéndolos en Lista, etc.:

 foreach (var key in filtered.Keys) { Console.WriteLine(key + " = " + filtered[key]); } 

espero que esto ayude.

No hay necesidad de reflexión:

 int value = (int)TestEnum.TestOne; 

Hola tienes esta alternativa:

Type typevar = GetType([YourEnum])

Y luego … … Puede obtener nombres usando typevar.GetEnumNames devolviendo una matriz con nombres y para obtener valores usando type.GetEnumValues , devolviendo una matriz con valores.

Este artículo es el mejor para ti usando la reflexión con Enums: Enum Reflection

En mi caso, el problema fue que MyEnum no se encontró debido a un signo + que obtiene el tipo de ensamblaje (línea 2):

 var dll = System.Reflection.Assembly.LoadFile("pathToDll"); Type myEnum = dll.GetType("namespace+MyEnum"); System.Array myEnumValues = System.Enum.GetValues(myEnum); 

Así de simple.

 var value = propertyInfo.GetValue(obj); // this return TestOne or TestTwo var enumValue = Convert.ChangeType(value, typeof(int)); // this return 3 or 4 

O, si necesita el objeto de enumeración real (de tipo TestEnum):

 MemberInfo[] memberInfos = typeof(MyEnum).GetMembers(BindingFlags.Public | BindingFlags.Static); string alerta = ""; for (int i = 0; i < memberInfos.Length; i++) { alerta += memberInfos[i].Name + " - "; /* alerta += memberInfos[i].GetType().Name + "\n"; */ // the actual enum object (of type MyEnum, above code is of type System.Reflection.RuntimeFieldInfo) object enumValue = memberInfos[i].GetValue(0); alerta += enumValue.ToString() + "\n"; } 
 System.Type.GetType("Namespace Name" + "." + "Class Name" + "+" + "Enum Name") Dim fieldInfos() As System.Reflection.FieldInfo = System.Type.GetType("YourNameSpaceName.TestClass+TestEnum").GetFields For Each f As System.Reflection.FieldInfo In fieldInfos If f.IsLiteral Then MsgBox(f.Name & " : " & CType(f.GetValue(Nothing), Integer) & vbCrLf) End If Next Public Class TestClass Public Enum TestEnum val1 = 20 val2 = 30 End Enum End Class 

Eso funciona