通过反射获取Enum值
我有一个简单的枚举
public enum TestEnum
{
TestOne = 3,
TestTwo = 4
}
var testing = TestEnum.TestOne;
,我想通过反射检索它的值 (3)。关于如何做到这一点有什么想法吗?
I have a simple Enum
public enum TestEnum
{
TestOne = 3,
TestTwo = 4
}
var testing = TestEnum.TestOne;
And I want to retrieve its value (3) via reflection. Any ideas on how to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
很好的问题,马特。
问题的场景是这样的:
这是使用反射执行此操作的单行方法:
如果 value 恰好是 TestEnum.TestTwo,则 value.GetType() 将等于 typeof (TestEnum)、
Enum.GetUnderlyingType(value.GetType())
将等于typeof(int)
并且 value 将为 3(盒装;请参阅 < a href="http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx" rel="noreferrer">http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx< /a> 有关装箱和拆箱值的更多详细信息)。为什么需要编写这样的代码?就我而言,我有一个将值从视图模型复制到模型的例程。我在 ASP.NET MVC 项目的所有处理程序中使用它,作为非常干净和优雅的架构的一部分,用于编写处理程序,这些处理程序不存在 Microsoft 模板生成的处理程序所存在的安全问题。
该模型由实体框架从数据库生成,它包含一个 int 类型的字段。视图模型有一个某种枚举类型的字段,我们称之为 RecordStatus,我在项目的其他地方定义了它。我决定在我的框架中完全支持枚举。但现在模型中字段的类型与视图模型中相应字段的类型不匹配。我的代码检测到这一点,并使用类似于上面给出的单行代码的代码将枚举转换为 int。
Great question Mat.
The scenario of the question is this:
This is the one-line way of doing this using reflection:
If value happens to be
TestEnum.TestTwo
, thenvalue.GetType()
would be equal totypeof(TestEnum)
,Enum.GetUnderlyingType(value.GetType())
would be equal totypeof(int)
and value would be 3 (boxed; see http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx for more details about boxing and unboxing values).Why would one ever need to write such code? In my case, I have a routine that copies values from a viewmodel to a model. I use this in all my handlers in an ASP.NET MVC project as part of a very clean and elegant architecture for writing handlers that do not have the security problems the handlers generated by the Microsoft templates do.
The model is generated by the Entity Framework from the database and it contains a field of type int. The viewmodel has a field of some enum type, let's call it RecordStatus, which I have defined elsewhere in my project. I decided to support enums fully in my framework. But now there is a mismatch between the type of the field in the model and the type of the corresponding field in the viewmodel. My code detects this and converts the enum to an int using the code similar to the one-liner given above.
您可以使用 System.Enum 帮助器:
输出
You can use the System.Enum helpers:
Outputs
完整代码:如何在 C# 中通过反射获取枚举值
Full code : How to Get Enum Values with Reflection in C#
如果您已在仅反射上下文中加载程序集,则 GetValue 和 GetValues 方法将不起作用。但我们可以使用另一种方法:
If you have loaded an assembly in reflection-only context the methods GetValue and GetValues don't work. But we can use another approach:
为什么需要反思?
Why do you need reflection?
对于您的要求,就像人们已经指出的那样简单。只需将枚举对象转换为 int 即可获得枚举的数值。
但是,如果需要使用 | 混合枚举值(按位或)例如
,您希望获得混合值代表的选项,您可以这样做(注意:这适用于由旨在利用按位运算的 int 值表示的枚举):
首先,获取枚举选项及其在字典中的值。
过滤字典以仅返回混合选项。
根据你的选择做任何逻辑。例如打印它们,将它们转为列表等......:
希望这会有所帮助。
For your requirement it's as simple as people already pointed it out. Just cast the enum object to int and you'd get the numeric value of the enum.
However, if there is a need to mix-down enum values with | (bitwise OR) e.g.
and you wish to get what options that mixed-down value represents, here is how you could do it (note: this is for enums that represented by int values intended to take advantage of bitwise operatations) :
first, get the enum options along with their values in a dictionary.
Filter the dictionary to return only the mixed-down options.
do whatever logic with your options. e.g. printing them, turning them to List, etc..:
hope this helps.
请尝试以下操作:
Try the following:
您可以使用 Gethashkey 函数获取未知类型的枚举值。
更多详细信息
动态获取枚举类型
读取枚举值
我希望它对某人有所帮助!
You can use the Gethashkey function to get the value of enum with an unknown type.
More details
Getting enum type dynamically
Reading enum values
I hope it helps someone!
使用此方法通过反射获取枚举 int 值
Get enum int value via reflection using this method
或者,如果您需要实际的枚举对象(TestEnum 类型):
Or, if you needed the actual enum object (of type TestEnum) :
你好,你有这个选择:
Type typevar = GetType([YourEnum])
然后...
...
您可以使用
typevar.GetEnumNames
返回包含名称的数组来获取名称,并使用type.GetEnumValues
返回包含值的数组来获取值。Hi you have this alternative:
Type typevar = GetType([YourEnum])
And then ...
...
You can get names using
typevar.GetEnumNames
returning a array with names and to get values usingtype.GetEnumValues
, returning an array with values.那行得通
That works
很简单。
Just simple.
无需反思:
No need for reflection:
就我而言,问题是由于 + 号从程序集获取类型(第 2 行)而未找到 MyEnum:
In my case, the problem was MyEnum not been found due to a + sign getting type from assembly (line 2):
提出这样的问题一定是有动机的。在这里,我有一个现实生活场景,有很好的动机去做这样的事情,以及这个问题的解决方案。
动机
2 个带有循环引用的组件。一种引用是硬引用,即
项目文件中的
标记。以及相反方向的软参考。assemble1
必须调用assemble2
中的某个对象、某个方法。方法的参数是enum
这是获取枚举值的代码。程序集在调用此方法时已加载,因为包含方法的对象实例已加载
解决方案
以及用法
底线 - 当一个程序集不知道(并且不能了解)其他装配内部结构。
There must be a motivation to ask a question like this. Here I have one real life scenario with good motivation to do something like this and the solution to this problem.
Motivation
2 assemblies with circular references. One reference is hard reference, i.e.
<Reference . . .>
tag in project file. And a soft reference in opposite direction.assembly1
must call some object, some method inassembly2
. Method's argument isenum
Here is the code that will get enum value. The assembly is already loaded at the time of calling this method because instance of the object containing method already loaded
Solution
And the usage
Bottom line - it is really useful when one assembly has no idea (and can't have knowledge) of the other assembly internals.