【问题标题】: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”。

如何提取价值?

【问题讨论】:

标签: c# .net reflection properties enums


【解决方案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();
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    相关资源
    最近更新 更多