如何从枚举中获取数值?

Posted

技术标签:

【中文标题】如何从枚举中获取数值?【英文标题】:How to get the numeric value from the Enum? 【发布时间】:2010-12-05 04:13:01 【问题描述】:

例如 System.Net.HttpStatusCode 枚举,我想获取 HTTP 状态代码而不是 HTTP 状态文本。 System.Net.HttpStatusCode.Forbidden 应该返回 403 而不是“Forbidden”。

如何提取价值?

【问题讨论】:

Getting Http Status code number (200, 301, 404, etc.) from HttpWebRequest and HttpWebResponse的可能重复 【参考方案1】:

对于大多数 Enum 来说,只是简单地转换为 int32 的基本类型。

int value = (int)System.Net.HttpStatusCode.Forbidden;

【讨论】:

什么是少数不能简单转换的例子? @Jimmy,任何具有不同基本类型的枚举。在这些情况下,您只需转换为适当的基本类型(uint32 等)... 我可能会补充一点,您可以使用静态 Enum.GetUnderlyingType(typeof(MyEnum)) 方法获取枚举的底层类型。 你可以使用更好的方法 => int value = System.Net.HttpStatusCode.Forbidden.GetHashCode(); 【参考方案2】:

您可以将其转换为整数!

int code = (int)enumVariable

【讨论】:

你可以使用有原则的方式 => int value = System.Net.HttpStatusCode.Forbidden.GetHashCode(); -【参考方案3】:

System.Convert.ToInt32(response.StatusCode) 返回statusCode编号

【讨论】:

当你有一个枚举,但你没有枚举类型时,这有效。例如。 void DoSomethingWithEnum(Enum value) int X = Convert.ToInt32(value); 在这种情况下,正常转换为 int 不起作用。 如果您的枚举是泛型类型参数,这也很有效。 Visual Studio 代码分析可能会生成警告 CA1305,“'Convert.ToInt32(object)' 的行为可能因当前用户的区域设置而异。”在这种情况下,我倾向于回到良好的旧转换语法。【参考方案4】:

我认为 @JaredPar 的答案很棒,但正如他自己解释的那样,它并不总是有效,所以我会在这里提供一个完整的答案。

简短的回答

不要简单地进行强制转换,而是使用以下代码

var value = 
    typeof(System.Net.HttpStatusCode)
        .GetField("value__")
        .GetValue(System.Net.HttpStatusCode.Forbidden);

Console.WriteLine(value); // 403

现在让我们详细说明一下...

Enum 的数值并不总是 int (!!!)

正如Docu中解释的那样,

每个枚举类型都有一个对应的整数类型,称为枚举类型的基础类型。此基础类型必须能够表示枚举中定义的所有枚举值。 枚举声明可以显式声明 byte、sbyte、short、ushort、int、uint、long 或 ulong 的基础类型。请注意,char 不能用作基础类型。未显式声明基础类型的枚举声明具有 int 基础类型。

所以,假设您正在处理一个声明为

枚举
enum LongEnum : long 
 
    min = long.MinValue, 
    max = long.MaxValue 

通过应用 @JaredPar 给出的解决方案

int value = (int)LongEnum.min;

你会得到以下错误:

错误 CS0221:常量值 '-9223372036854775808' 无法转换为 'int'(使用 'unchecked' 语法覆盖)

所以,为了解决这个问题,正如您在上面看到的,诀窍当然是使用 Reflection

object value =
    typeof(LongEnum)
    .GetField("value__")
    .GetValue(LongEnum.min);

Console.WriteLine(value); // -9223372036854775808

打印正确的值!

但是......枚举的'value__'字段是什么???

要回答这个问题,我会关注@Hans Passant 的an answer:

JIT 编译器需要一个值类型的定义来描述它在装箱时的布局。它们中的大多数都被嵌入到 mscorlib 中,例如 System.Int32。 enum 关键字允许您创建新的值类型。因此,编译器必须在元数据中为其提供定义。这就是您正在查看的内容。您将看到 ToString() 使用的每个枚举成员的静态字段。以及一个存储枚举值的实例字段名 value__。关键是这只存在于枚举值的盒装版本中。

附注...

由于我们的解决方案返回 object 类型的值,因此有人会想修改 @JaredPar 的答案,如下所示

Object value = (object)LongEnum.min;

Console.WriteLine(value);

不过,这只会打印 member 名称 min

【讨论】:

【参考方案5】:

您可以使用 .NET CLR 函数以一种有原则的方式..

int value = System.Net.HttpStatusCode.Forbidden.GetHashCode();

【讨论】:

你不应该依赖GetHashCode()来工作,总是这样工作。详情请见***.com/a/4584686/879553。

以上是关于如何从枚举中获取数值?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Rails 中的枚举中获取整数值?

如何在使用IMetadataImport时获取枚举值

如何获取一个枚举类型元素的个数

如何将mysql中枚举类型的数值在前台遍历为汉字

如何从 EventLogEntryType 枚举中获取 int 值 [重复]

如何从Swift的原始值中获取枚举?