通过reflection获取枚举值
我有一个简单的枚举
public enum TestEnum { TestOne = 3, TestTwo = 4 } var testing = TestEnum.TestOne;
我想通过reflection来检索它的值(3)。 任何想法如何做到这一点?
伟大的问题垫。
这个问题的场景是这样的:
你有一些未知的枚举types和这个types的一些未知的值 ,你想获得该未知值的基础数值 。
这是使用reflection的一种方式:
object underlyingValue = Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType()));
如果值恰好是TestEnum.TestTwo
,那么value.GetType()
将等于typeof(TestEnum)
, Enum.GetUnderlyingType(value.GetType())
将等于typeof(int)
,值将为3(boxed;请参阅http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx关于装箱和取消装箱值的更多细节)。;
为什么会有人需要写这样的代码? 就我而言,我有一个例程,从视图模型复制值到模型。 我在ASP.NET MVC项目的所有处理程序中都使用了这个function,作为编写处理程序的非常干净优雅的体系结构的一部分,它没有Microsoft模板生成的处理程序所产生的安全问题。
该模型由entity framework从数据库生成,并包含一个inttypes的字段。 viewmodel有一些枚举types的字段,我们称之为RecordStatus,这是我在项目中其他地方定义的。 我决定在我的框架中完全支持枚举。 但现在模型中的字段types与视图模型中相应字段的types之间存在不匹配。 我的代码检测到这一点,并使用类似于上面给出的单行代码将枚举转换为int。
您可以使用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); }
输出
3
4
完整的代码: 如何在C#中使用reflection获取枚举值
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"; }
你为什么需要反思?
int value = (int)TestEnum.TestOne;
尝试以下操作:
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)));
对于您的要求,就像人们已经指出的一样简单。 只需将枚举对象转换为int,您将获得枚举的数值。
int value = (int) TestEnum.TestOne;
但是,如果需要将枚举值与|混合在一起 (按位或)例如
var value = TestEnum.TestOne | TestEnum.TestTwo;
并且希望得到混合值表示的选项,下面是如何做到这一点(请注意:这是针对int值表示的枚举,旨在利用按位运算):
首先,在字典中获取枚举选项及其值。
var all_options_dic = typeof(TestEnum).GetEnumValues().Cast<object>().ToDictionary(k=>k.ToString(), v=>(int) v);
筛选字典以仅返回混合选项。
var filtered = all_options_dic.Where(x => (x.Value & (int) options) != 0).ToDictionary(k=>k.Key, v=>v.Value);
用你的select做任何逻辑。 如打印他们,把他们转到列表等。
foreach (var key in filtered.Keys) { Console.WriteLine(key + " = " + filtered[key]); }
希望这可以帮助。
不需要反思:
int value = (int)TestEnum.TestOne;
嗨,你有这个select:
Type typevar = GetType([YourEnum])
然后… …您可以使用typevar.GetEnumNames
获取名称,返回一个名称数组,并使用type.GetEnumValues
获取值,返回一个包含值的数组。
这篇文章是最适合你使用reflection与枚举: 枚举reflection
在我的情况下,问题是没有findMyEnum由于+符号从程序集中获取types(第2行):
var dll = System.Reflection.Assembly.LoadFile("pathToDll"); Type myEnum = dll.GetType("namespace+MyEnum"); System.Array myEnumValues = System.Enum.GetValues(myEnum);
很简单。
var value = propertyInfo.GetValue(obj); // this return TestOne or TestTwo var enumValue = Convert.ChangeType(value, typeof(int)); // this return 3 or 4
或者,如果您需要实际的枚举对象(typesTestEnum):
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
这样可行