Obtendo valor Enum via reflection

Eu tenho um simples Enum

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

E eu quero recuperar seu valor (3) via reflection. Algumas ideias em como fazer isso?

Grande pergunta Mat.

O cenário da questão é este:

Você tem algum tipo de enum desconhecido e algum valor desconhecido desse tipo e deseja obter o valor numérico subjacente desse valor desconhecido.

Esta é a maneira de fazer uma linha usando a reflection:

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

Se o valor for TestEnum.TestTwo , value.GetType() seria igual a typeof(TestEnum) , Enum.GetUnderlyingType(value.GetType()) seria igual a typeof(int) e value seria 3 (boxed; veja http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx para mais detalhes sobre valores de boxe e unboxing).

Por que alguém precisaria escrever esse código? No meu caso, tenho uma rotina que copia valores de um viewmodel para um modelo. Eu uso isso em todos os meus manipuladores em um projeto ASP.NET MVC como parte de uma arquitetura muito limpa e elegante para escrever manipuladores que não têm os problemas de segurança que os manipuladores gerados pelos modelos da Microsoft.

O modelo é gerado pelo Entity Framework a partir do database e contém um campo do tipo int. O viewmodel tem um campo de algum tipo enum, vamos chamá-lo RecordStatus, que eu defini em outro lugar no meu projeto. Eu decidi apoiar enums totalmente no meu framework. Mas agora há uma incompatibilidade entre o tipo do campo no modelo e o tipo do campo correspondente no modelo de visualização. Meu código detecta isso e converte o enum para um int usando o código semelhante ao one-liner dado acima.

Você pode usar os auxiliares 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); } 

Saídas

3
4

Código completo: How to Get Enum Values ​​with Reflection in 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 que você precisa de reflection?

 int value = (int)TestEnum.TestOne; 

Tente o seguinte:

 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 sua exigência, é tão simples quanto as pessoas já apontaram. Apenas lance o object enum para int e você obteria o valor numérico do enum.

 int value = (int) TestEnum.TestOne; 

No entanto, se houver a necessidade de misturar valores enum com | (bit a bit OR) por exemplo

 var value = TestEnum.TestOne | TestEnum.TestTwo; 

e você deseja obter as opções que o valor misturado representa, aqui está como você poderia fazê-lo (note: isto é para enums representados por valores int destinados a aproveitar as operações bitwise):

primeiro, obtenha as opções enum junto com seus valores em um dictionary.

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

Filtre o dictionary para retornar apenas as opções misturadas.

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

faça qualquer lógica com suas opções. por exemplo, imprimindo-os, transformando-os em List, etc.

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

espero que isto ajude.

Não há necessidade de reflection:

 int value = (int)TestEnum.TestOne; 

Oi você tem essa alternativa:

Type typevar = GetType([YourEnum])

E então … … Você pode obter nomes usando typevar.GetEnumNames retornando uma matriz com nomes e para obter valores usando type.GetEnumValues , retornando uma matriz com valores.

este artigo é melhor para você usando reflection com Enums: Enum Reflection

No meu caso, o problema foi MyEnum não foi encontrado devido a um sinal de + recebendo tipo de assembly (linha 2):

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

Simples.

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

Ou, se você precisava do object enum real (do 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 

Isso funciona