How to get the numeric value from the Enum?

50,407

Solution 1

For the majority of Enum's simply cast to the base type which is int32.

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

Solution 2

You can just cast it to an integer!

int code = (int)enumVariable

Solution 3

System.Convert.ToInt32(response.StatusCode) returns the statusCode number

Solution 4

I think @JaredPar's answer is great, but as he himself explains it does not always work, so i will offer a complete answer here.

The short answer

Instead of simply casting, use the following code

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

Console.WriteLine(value); // 403

Now lets elaborate a bit on this...

Numeric value of Enum is not always int (!!!)

As explained in the Docu,

Each enum type has a corresponding integral type called the underlying type of the enum type. This underlying type must be able to represent all the enumerator values defined in the enumeration. An enum declaration may explicitly declare an underlying type of byte, sbyte, short, ushort, int, uint, long or ulong. Note that char cannot be used as an underlying type. An enum declaration that does not explicitly declare an underlying type has an underlying type of int.

So, lets imagine you are dealing with an enum that is declared as

enum LongEnum : long 
{ 
    min = long.MinValue, 
    max = long.MaxValue 
}

by applying the solution given by @JaredPar

int value = (int)LongEnum.min;

you will get the following error:

error CS0221: Constant value '-9223372036854775808' cannot be converted to a 'int' (use 'unchecked' syntax to override)

So, in order to get around this, the trick is of course, as you saw above, to use Reflection:

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

Console.WriteLine(value); // -9223372036854775808

which prints the right value!

But... what is that 'value__' field of enum???

To answer this, i will follow an answer of @Hans Passant:

The JIT compiler needs a definition of a value type that describes its layout when it gets boxed. Most of them are baked into mscorlib, like System.Int32. The enum keyword lets you create a new value type. The compiler must thus provide a definition for it in the metadata. Which is what you are looking at. You'll see static fields for each enumeration member, used by ToString(). And one instance field name value__ that stores the enumeration value. Key point is that this only exists in the boxed version of an enum value.

P.S. ...

Since our solution returns a value of type object, someone would be tempted to modify @JaredPar's answer as follows

Object value = (object)LongEnum.min;

Console.WriteLine(value);

nevertheless, that will just print the member name min.

Share:
50,407
kurozakura
Author by

kurozakura

Updated on July 05, 2022

Comments

  • kurozakura
    kurozakura almost 2 years

    For example System.Net.HttpStatusCode Enum, I would like to get the HTTP Status Codes instead of the HTTP Status Text. System.Net.HttpStatusCode.Forbidden should return 403 instead of "Forbidden".

    How can I extract the value?

  • Boti
    Boti over 14 years
    what is an example of a minority that cannot be simply cast?
  • JaredPar
    JaredPar over 14 years
    @Jimmy, any enum which has a different base type. In those cases you just need to cast to the appropriate base type (uint32, etc)...
  • Yoopergeek
    Yoopergeek over 14 years
    I might add that you can get the enum's underlying type by using the static Enum.GetUnderlyingType(typeof(MyEnum)) method.
  • Martin Lottering
    Martin Lottering about 11 years
    This works when you have an enum, but you don't have the type of enum. E.g. void DoSomethingWithEnum(Enum value) { int X = Convert.ToInt32(value); } In this case a normal cast to int doesn't work.
  • Jay
    Jay over 8 years
    This also works very well if your enum is a generic type parameter.
  • R.Akhlaghi
    R.Akhlaghi almost 5 years
    you can use a better way => { int value = System.Net.HttpStatusCode.Forbidden.GetHashCode(); }
  • R.Akhlaghi
    R.Akhlaghi almost 5 years
    you can use a principled way => { int value = System.Net.HttpStatusCode.Forbidden.GetHashCode(); } –
  • Sandro
    Sandro over 4 years
    You shouldn't rely on GetHashCode() to work alwys work like this. See stackoverflow.com/a/4584686/879553 for details.
  • Phil Jollans
    Phil Jollans over 3 years
    Visual Studio code analysis might generate warning CA1305, "The behavior of 'Convert.ToInt32(object)' could vary based on the current user's locale settings." In this case I am inclined to go back to the good old cast syntax.