c# - How can I cast int to enum?

ID : 123

viewed : 343

Tags : c#enumscastingintc#

Top 5 Answer for c# - How can I cast int to enum?

vote vote


From an int:

YourEnum foo = (YourEnum)yourInt; 

From a string:

YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString);  // The foo.ToString().Contains(",") check is necessary for enumerations marked with an [Flags] attribute if (!Enum.IsDefined(typeof(YourEnum), foo) && !foo.ToString().Contains(",")) {     throw new InvalidOperationException($"{yourString} is not an underlying value of the YourEnum enumeration.") } 


From number you can also

YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt); 
vote vote


Just cast it:

MyEnum e = (MyEnum)3; 

You can check if it's in range using Enum.IsDefined:

if (Enum.IsDefined(typeof(MyEnum), 3)) { ... } 
vote vote


Alternatively, use an extension method instead of a one-liner:

public static T ToEnum<T>(this string enumString) {     return (T) Enum.Parse(typeof (T), enumString); } 


Color colorEnum = "Red".ToEnum<Color>(); 


string color = "Red"; var colorEnum = color.ToEnum<Color>(); 
vote vote


I think to get a complete answer, people have to know how enums work internally in .NET.

How stuff works

An enum in .NET is a structure that maps a set of values (fields) to a basic type (the default is int). However, you can actually choose the integral type that your enum maps to:

public enum Foo : short 

In this case the enum is mapped to the short data type, which means it will be stored in memory as a short and will behave as a short when you cast and use it.

If you look at it from a IL point of view, a (normal, int) enum looks like this:

.class public auto ansi serializable sealed BarFlag extends System.Enum {     .custom instance void System.FlagsAttribute::.ctor()     .custom instance void ComVisibleAttribute::.ctor(bool) = { bool(true) }      .field public static literal valuetype BarFlag AllFlags = int32(0x3fff)     .field public static literal valuetype BarFlag Foo1 = int32(1)     .field public static literal valuetype BarFlag Foo2 = int32(0x2000)      // and so on for all flags or enum values      .field public specialname rtspecialname int32 value__ } 

What should get your attention here is that the value__ is stored separately from the enum values. In the case of the enum Foo above, the type of value__ is int16. This basically means that you can store whatever you want in an enum, as long as the types match.

At this point I'd like to point out that System.Enum is a value type, which basically means that BarFlag will take up 4 bytes in memory and Foo will take up 2 -- e.g. the size of the underlying type (it's actually more complicated than that, but hey...).

The answer

So, if you have an integer that you want to map to an enum, the runtime only has to do 2 things: copy the 4 bytes and name it something else (the name of the enum). Copying is implicit because the data is stored as value type - this basically means that if you use unmanaged code, you can simply interchange enums and integers without copying data.

To make it safe, I think it's a best practice to know that the underlying types are the same or implicitly convertible and to ensure the enum values exist (they aren't checked by default!).

To see how this works, try the following code:

public enum MyEnum : int {     Foo = 1,     Bar = 2,     Mek = 5 }  static void Main(string[] args) {     var e1 = (MyEnum)5;     var e2 = (MyEnum)6;      Console.WriteLine("{0} {1}", e1, e2);     Console.ReadLine(); } 

Note that casting to e2 also works! From the compiler perspective above this makes sense: the value__ field is simply filled with either 5 or 6 and when Console.WriteLine calls ToString(), the name of e1 is resolved while the name of e2 is not.

If that's not what you intended, use Enum.IsDefined(typeof(MyEnum), 6) to check if the value you are casting maps to a defined enum.

Also note that I'm explicit about the underlying type of the enum, even though the compiler actually checks this. I'm doing this to ensure I don't run into any surprises down the road. To see these surprises in action, you can use the following code (actually I've seen this happen a lot in database code):

public enum MyEnum : short {     Mek = 5 }  static void Main(string[] args) {     var e1 = (MyEnum)32769; // will not compile, out of bounds for a short      object o = 5;     var e2 = (MyEnum)o;     // will throw at runtime, because o is of type int      Console.WriteLine("{0} {1}", e1, e2);     Console.ReadLine(); } 
vote vote


Take the following example:

int one = 1; MyEnum e = (MyEnum)one; 

Top 3 video Explaining c# - How can I cast int to enum?