通过反射获得枚举值

mat*_*lin 39 c# reflection enums

我有一个简单的枚举

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

var testing = TestEnum.TestOne;
Run Code Online (Sandbox Code Playgroud)

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

Mil*_*dis 49

好问题垫.

问题的情景如下:

您有一些未知的枚举类型和该类型的某些未知值,并且您希望获得该未知值的基础数值.

这是使用反射执行此操作的单行方式:

object underlyingValue = Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType()));
Run Code Online (Sandbox Code Playgroud)

如果值恰好是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模板生成的处理程序所带来的安全问题.

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

  • 感谢您的评论,但实际上这*是Mat问的问题的答案. (6认同)
  • 你的答案很好地回答了你自己提出的问题,但我不认为这是对这里提出的问题的答案. (3认同)
  • 更具体地说,Mat询问他如何使用反射*获得某个简单枚举类型(TestEnum)*的枚举值(测试)的(基础)值(3).丹尼尔和弗雷德里克认为他问错了,并回答说反射是不必要的,Pranay完全回答了一个不同的问题(如何使用反射列出枚举类型的值).这正是因为目前赞成的答案没有解决我问过的问题,我回答了这个问题,然后给出了一个例子,说明人们可能想要完全按照Mat所要求的那样做!:-) (3认同)
  • @hvd:感谢您的评论.我要说的是传递给Convert.ChangeType的第二个参数是一个类型对象(即System.Type类型的对象,它是System.Reflection.MemberInfo的子类)意味着即使转换本身*也是*使用.NET CLR的反射基础架构!所以,我认为我没有忽略Mat的问题中的要求,也不认为他首先添加它是错误的!如果没有这个要求,看起来Mat就像Fredrik和Daniel给出的答案一样. (2认同)
  • 我回答了问题,因为它没有试图猜测或怀疑Mat能够表达他想要的东西.如果,正如你所说,他希望能够从"TestEnum.TestOne"变为3而不是从TestEnum.TestOne变为3使用反射,那么我会同意他的问题并没有传达出来.但就目前而言,这是一个非常合理的问题,现在它有了答案.:-) @mjmcloug:有什么意见吗? (2认同)

OLP*_*OLP 31

您可以使用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);
}
Run Code Online (Sandbox Code Playgroud)

输出

3
4

  • 这是更好的答案.因为我在这里遇到了同样的问题,我意识到这是一个XY问题.反思不是我需要的. (6认同)
  • 并非所有的枚举都是整齐的!枚举也可以是sbyte,byte,short,ushort,uint,long,ulong和char.您应该转换为基础类型,如接受的答案所示. (4认同)

Pra*_*ana 21

完整代码:如何在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";
}
Run Code Online (Sandbox Code Playgroud)

  • 我没有-1,但我猜,即使答案是正确的,它也不是很具描述性.这是一个链接和一些代码,弄清楚.它可以通过几种方式变得更好,其中一种方法是提供样本输出. (10认同)

Dan*_*ite 7

你为什么需要反思?

int value = (int)TestEnum.TestOne;
Run Code Online (Sandbox Code Playgroud)

  • ;)是的,我知道如何这样做.但我需要使用反射 (6认同)
  • 这是因为我们不知道TestEnum的类型,我们只知道我们有一个枚举. (3认同)

Ser*_*eyT 6

如果您已在仅反射上下文中加载程序集,则 GetValue 和 GetValues 方法将不起作用。但我们可以使用另一种方法:

var val = typeof(MyEnum).GetFields()
    .Where(fi => fi.IsLiteral && fi.Name == "TestOne")
    .Select(fi => fi.GetRawConstantValue())
    .First();
Run Code Online (Sandbox Code Playgroud)