2010-08-25 86 views
34

枚举值我有一个简单枚举获得通过反射

public enum TestEnum 
{ 
    TestOne = 3, 
    TestTwo = 4 
} 

var testing = TestEnum.TestOne; 

我想要检索通过反射它的值(3)。任何想法如何做到这一点?

+0

要发表评论:在任何意义上'有'TestEnum.TestOne值的环境中,*已经*值为'3'。你实际上有什么? – AakashM 2010-08-25 12:01:27

回答

38

伟大的问题垫。

问题的情形是这样的:

你有一些未知的枚举类型和一些未知值类型的,你想获取未知值的基础数值

这是这样使用反射的一个联机方式:

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

如果值碰巧是TestEnum.TestTwo,然后value.GetType()将等于typeof(TestEnum)Enum.GetUnderlyingType(value.GetType())将等于typeof(int)和值将是3(装箱;有关装箱和拆箱值的更多详细信息,请参阅http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx)。

为什么有人需要编写这样的代码?就我而言,我有一个将视图模型中的值复制到模型的例程。我在ASP.NET MVC项目的所有处理程序中都使用它作为非常干净优雅的编写处理程序的一部分,该处理程序没有Microsoft模板生成的处理程序所产生的安全问题。

该模型由Entity Framework从数据库生成,它包含一个int类型的字段。 viewmodel有一些枚举类型的字段,我们称之为RecordStatus,这是我在项目中其他地方定义的。我决定在我的框架中完全支持枚举。但现在模型中的字段类型与视图模型中相应字段的类型之间存在不匹配。我的代码检测到这一点,并使用类似于上面给出的单行代码将枚举转换为int。

+3

你的回答对你自问的问题是一个很好的答案,但我不认为这是对这里提出的问题的回答。 – hvd 2012-11-14 11:48:56

+6

感谢您的评论,但实际上这*是* Mat问的答案。 – 2012-11-16 08:40:19

+3

更具体地说,Mat问他如何使用反射*获取某个简单枚举类型(TestEnum)*的枚举值(测试)的(基础)值(3)。丹尼尔和弗雷德里克假定他问的是错误的东西,并回答说反射是不必要的,普兰奈完全回答了一个不同的问题(如何使用反射列出枚举类型的值)。这正是因为目前有回应的答案没有解决我提出的问题,并且回答了这个问题,并举了一个例子,说明一个人可能想要完全按照Mat的要求去做的事情! :-) – 2012-11-16 09:03:08

1

无需反思:

int value = (int)TestEnum.TestOne; 
+0

又一次我知道如何做到这一点。但我需要使用反射 – 2010-08-25 11:41:42

+6

@mjmcloug:如果你扩展你的问题的简要信息*为什么*你需要使用反射和你的用例,你会得到更好的答案:) – 2010-08-25 11:48:20

5

为什么你需要反思?

int value = (int)TestEnum.TestOne; 
+1

伟大的思想认为一样。并在同一秒,似乎:) – 2010-08-25 11:28:05

+6

;)是的,我知道如何做到这一点。但我需要使用反射 – 2010-08-25 11:41:15

+2

这是因为我们不知道TestEnum类型,我们只知道我们有一个枚举。 – 2014-02-27 16:17:22

16

全码: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"; 
} 
+10

我没有-1,但我猜测即使答案是正确的,但它不是很具描述性。这里有一个链接和一些代码,弄清楚。它可以通过几种方式变得更好,其中之一是提供样本输出。 – 2013-09-22 20:27:02

-1

或者,如果你需要的(类型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"; 
} 
19

您可以使用系统。枚举助手:

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); 
} 

输出

+4

这是更好的答案。因为我在这里遇到同样的问题,我意识到这是一个XY问题。反思不是我所需要的。 – Bitterblue 2013-11-18 12:08:15

+1

当我将其转换为int(.Net 4.5)时,出现此错误“类型为'System.InvalidCastException'的未处理异常”。 – 2014-02-27 16:19:35

+4

并非所有的枚举都是int!枚举也可以是sbyte,byte,short,ushort,uint,long,ulong和char。正如接受的答案所暗示的,你应该投下基础类型。 – 2014-10-17 07:17:42

2

尝试以下操作:

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))); 
0

只是简单的。

var value = propertyInfo.GetValue(obj); // this return TestOne or TestTwo 

var enumValue = Convert.ChangeType(value, typeof(int)); // this return 3 or 4 
1

嗨,你有这样的选择:

Type typevar = GetType([YourEnum])

然后... ... 您 可以开始使用type.GetEnumValues使用typevar.GetEnumNames返回其名称和数组名称值获得,返回包含值的数组。

-1
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 

这一工程

+0

但它不是C# – 2016-01-15 12:38:13

0

对我来说,这个问题是MyEnum尚未发现因+号从装配越来越式(2号线):

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

对于您的要求是为很简单,因为人们已经指出了它。只需将枚举对象转换为int,即可获得枚举的数值。

int value = (int) TestEnum.TestOne; 

但是,如果需要混用枚举值| (按位或),例如

var value = TestEnum.TestOne | TestEnum.TestTwo; 

,你希望得到什么混合降值表示,这里是你如何能做到这一点(注:这是由打算采取按位operatations的优势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); 

对你的选择做任何逻辑。例如打印它们,将它们转到列表等。:

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

希望这有助于。