70

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?

1

4 Answers 4

108

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

int value = (int)System.Net.HttpStatusCode.Forbidden; 
Sign up to request clarification or add additional context in comments.

4 Comments

what is an example of a minority that cannot be simply cast?
@Jimmy, any enum which has a different base type. In those cases you just need to cast to the appropriate base type (uint32, etc)...
I might add that you can get the enum's underlying type by using the static Enum.GetUnderlyingType(typeof(MyEnum)) method.
you can use a better way => { int value = System.Net.HttpStatusCode.Forbidden.GetHashCode(); }
22

You can just cast it to an integer!

int code = (int)enumVariable 

1 Comment

you can use a principled way => { int value = System.Net.HttpStatusCode.Forbidden.GetHashCode(); } –
13

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.

Comments

11

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

4 Comments

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.
This also works very well if your enum is a generic type parameter.
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.
This is the solution you need for Razor templates. The 'System' namespace can be omitted, at least in .NET Core 8.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.