By lomaxx


2008-08-27 03:58:21 8 Comments

How can an int be cast to an enum in C#?

27 comments

@Aswal 2019-10-17 07:52:36

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace SamplePrograme
{
    public class Program
    {
        public enum Suit : int
        {
            Spades = 0,
            Hearts = 1,
            Clubs = 2,
            Diamonds = 3
        }

        public static void Main(string[] args)
        {
            //from string
            Console.WriteLine((Suit) Enum.Parse(typeof(Suit), "Clubs"));

            //from int
            Console.WriteLine((Suit)1);

            //From number you can also
            Console.WriteLine((Suit)Enum.ToObject(typeof(Suit) ,1));
        }
    }
}

@Tom 2019-10-17 08:14:53

Consider adding any explanation to your code.

@user11523568 2019-07-02 19:58:58

You should build in some type matching relaxation to be more robust.

public static T ToEnum<T>(dynamic value)
{
    if (value == null)
    {
        // default value of an enum is the object that corresponds to
        // the default value of its underlying type
        // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/default-values-table
        value = Activator.CreateInstance(Enum.GetUnderlyingType(typeof(T)));
    }
    else if (value is string name)
    {
        return (T)Enum.Parse(typeof(T), name);
    }

    return (T)Enum.ToObject(typeof(T),
             Convert.ChangeType(value, Enum.GetUnderlyingType(typeof(T))));
}

Test Case

[Flags]
public enum A : uint
{
    None  = 0, 
    X     = 1 < 0,
    Y     = 1 < 1
}

static void Main(string[] args)
{
    var value = EnumHelper.ToEnum<A>(7m);
    var x = value.HasFlag(A.X); // true
    var y = value.HasFlag(A.Y); // true

    var value2 = EnumHelper.ToEnum<A>("X");

    var value3 = EnumHelper.ToEnum<A>(null);

    Console.ReadKey();
}

@Mselmi Ali 2019-07-27 07:48:20

You just do like below:

int intToCast = 1;
TargetEnum f = (TargetEnum) intToCast ;

To make sure that you only cast the right values ​​and that you can throw an exception otherwise:

int intToCast = 1;
if (Enum.IsDefined(typeof(TargetEnum), intToCast ))
{
    TargetEnum target = (TargetEnum)intToCast ;
}
else
{
   // Throw your exception.
}

Note that using IsDefined is costly and even more than just casting, so it depends on your implementation to decide to use it or not.

@Chad Hedgcock 2019-02-22 01:31:39

Here's an extension method that casts Int32 to Enum.

It honors bitwise flags even when the value is higher than the maximum possible. For example if you have an enum with possibilities 1, 2, and 4, but the int is 9, it understands that as 1 in absence of an 8. This lets you make data updates ahead of code updates.

   public static TEnum ToEnum<TEnum>(this int val) where TEnum : struct, IComparable, IFormattable, IConvertible
    {
        if (!typeof(TEnum).IsEnum)
        {
            return default(TEnum);
        }

        if (Enum.IsDefined(typeof(TEnum), val))
        {//if a straightforward single value, return that
            return (TEnum)Enum.ToObject(typeof(TEnum), val);
        }

        var candidates = Enum
            .GetValues(typeof(TEnum))
            .Cast<int>()
            .ToList();

        var isBitwise = candidates
            .Select((n, i) => {
                if (i < 2) return n == 0 || n == 1;
                return n / 2 == candidates[i - 1];
            })
            .All(y => y);

        var maxPossible = candidates.Sum();

        if (
            Enum.TryParse(val.ToString(), out TEnum asEnum)
            && (val <= maxPossible || !isBitwise)
        ){//if it can be parsed as a bitwise enum with multiple flags,
          //or is not bitwise, return the result of TryParse
            return asEnum;
        }

        //If the value is higher than all possible combinations,
        //remove the high imaginary values not accounted for in the enum
        var excess = Enumerable
            .Range(0, 32)
            .Select(n => (int)Math.Pow(2, n))
            .Where(n => n <= val && n > 0 && !candidates.Contains(n))
            .Sum();

        return Enum.TryParse((val - excess).ToString(), out asEnum) ? asEnum : default(TEnum);
    }

@Shivam Mishra 2019-02-01 10:15:43

You simply use Explicit conversion Cast int to enum or enum to int

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine((int)Number.three); //Output=3

            Console.WriteLine((Number)3);// Outout three
            Console.Read();
        }

        public enum Number 
        {
            Zero = 0,
            One = 1,
            Two = 2,
            three = 3           
        }
    }

@Evan M 2011-04-13 20:13:13

If you have an integer that acts as a bitmask and could represent one or more values in a [Flags] enumeration, you can use this code to parse the individual flag values into a list:

for (var flagIterator = 0; flagIterator < 32; flagIterator++)
{
    // Determine the bit value (1,2,4,...,Int32.MinValue)
    int bitValue = 1 << flagIterator;

    // Check to see if the current flag exists in the bit mask
    if ((intValue & bitValue) != 0)
    {
        // If the current flag exists in the enumeration, then we can add that value to the list
        // if the enumeration has that flag defined
        if (Enum.IsDefined(typeof(MyEnum), bitValue))
            Console.WriteLine((MyEnum)bitValue);
    }
}

Note that this assumes that the underlying type of the enum is a signed 32-bit integer. If it were a different numerical type, you'd have to change the hardcoded 32 to reflect the bits in that type (or programatically derive it using Enum.GetUnderlyingType())

@Christian Gingras 2019-01-02 05:32:19

Is this loop never terminate? flagIterator = 0x00000001, flagIterator = 0x00000002, flagIterator = 0x00000004, ..., flagIterator = 0x40000000, flagIterator = 0x80000000, flagIterator = 0x00000000. In other words, the value will always be lower than 0x80000000 because it overflow to zero after the case where bit D31 = 1. Then, it remain 0 forever because shifting left the value 0 gives 0

@Evan M 2019-01-02 15:51:11

Great catch @christiangingras, thank you! I've modified the answer to account for that, and it should take into account when the highest bit is set (i.e. 0x80000000/Int32.MinValue)

@Mohammad Aziz Nabizada 2018-12-08 05:06:41

the easy and clear way for casting an int to enum in c#:

 public class Program
    {
        public enum Color : int
        {
            Blue = 0,
            Black = 1,
            Green = 2,
            Gray = 3,
            Yellow =4
        }

        public static void Main(string[] args)
        {
            //from string
            Console.WriteLine((Color) Enum.Parse(typeof(Color), "Green"));

            //from int
            Console.WriteLine((Color)2);

            //From number you can also
            Console.WriteLine((Color)Enum.ToObject(typeof(Color) ,2));
        }
    }

@Daniel Fisher lennybacon 2015-03-30 10:08:03

This is an flags enumeration aware safe convert method:

public static bool TryConvertToEnum<T>(this int instance, out T result)
  where T: Enum
{
  var enumType = typeof (T);
  var success = Enum.IsDefined(enumType, instance);
  if (success)
  {
    result = (T)Enum.ToObject(enumType, instance);
  }
  else
  {
    result = default(T);
  }
  return success;
}

@Scott 2018-11-09 17:03:02

This can now be improved with C# 7.3 by constraining to Enum instead of struct, meaning we don't have to rely on the runtime check!

@Kamran Shahid 2016-12-16 06:59:17

Following is slightly better extension method

public static string ToEnumString<TEnum>(this int enumValue)
        {
            var enumString = enumValue.ToString();
            if (Enum.IsDefined(typeof(TEnum), enumValue))
            {
                enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
            }
            return enumString;
        }

@FlySwat 2008-08-27 03:59:42

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 an int:

YourEnum foo = (YourEnum)yourInt;

Update:

From number you can also

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

@Tathagat Verma 2011-11-24 07:24:42

That correct it should be: YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString) OR YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourInt) -- As applicable.

@Shimmy 2012-02-19 09:56:20

@FlySwat, what if YourEnum is dynamic and will only be known at runtime, and what I want is to convert to Enum?

@Olivier Jacot-Descombes 2013-02-21 15:40:35

@Shimmy. If the enum is only known at runtime, keep it dynamic. Type safety (strong typing) can only be guaranteed by the compiler anyway. You cannot strongly type an object at runtime. The closest you can come to it is by using generics, but the generic type must be known at compile time. T ToEnum<T>(int x) { return (T)x; } but there is no real advantage over casting directly.

@Logan 2013-04-13 09:24:50

Quick question, if you were to go back from YourEnum foo to int anInt type: anInt = (int)foo; would that work?

@Jeppe Stig Nielsen 2013-04-15 18:05:37

@Logan Sure, it works. (If the underlying integer type of the enum is not int, cast to that underlying integer type instead. But it is extremely rare that the underlying type should be something else than simply int.)

@jropella 2013-04-26 18:03:41

Be aware that Enum.Parse will NOT work if your code is obfuscated. At run time after obfuscation the string is compared to the enum names, and at this point the names of the enums aren't what you would expect them to be. Your parse will fail where they succeeded before as a result.

@JoeCool 2013-06-25 15:14:30

BEWARE If you use the "from a string" syntax above and pass in an invalid string that is a number (e.g. "2342342" -- assuming that's not a value of your enum), it will actually allow that without throwing an error! Your enum will have that value (2342342) even though it's not a valid choice in the enum itself.

@Justin T Conroy 2013-11-26 21:40:18

I think this answer is a bit dated now. For string, you should really be using var result = Enum.TryParse(yourString, out yourEnum) nowadays (and checking the result to determine if the conversion failed).

@jackvsworld 2014-02-01 00:02:14

@JustinTConroy I don't know if I agree with that. In my programs, if the conversion fails it's often a non-recoverable error, so I want the exception to be thrown.

@Justin T Conroy 2014-02-03 17:28:06

The Parse function presents a classic example of a vexing exception. That is, an exception that is thrown in a completely non-exceptional circumstance, usually due to an unfortunate design decision. The developers of C# recognized this unfortunate design and later added TryParse to deal with this. TryParse returns a boolean that indicates if the parse succeeded or failed, so you should use that boolean instead of an exception handler. See Eric Lippert's blog post about vexing exceptions for more information.

@Erik Schierboom 2014-02-05 12:18:53

It is also possible to have Enum.Parse be case-insensitive by adding a true parameter value to the call: YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString, true);

@Santhos 2014-10-07 10:31:14

Is it possible that the conversion from int works even if the int value is not present in the enum? I just tried it in .net 3.5 and it seems to work which is quite confusing.

@Colin 2014-12-08 19:10:55

Enum.ToObject was what I was looking for. This is exactly what you need when working with enums dynamically and you have a type that you know is an enum but can't prove it to the compiler, which won't allow you to cast from an int value to an arbitrary type.

@Thaoden 2015-03-06 10:37:08

@Santhos Yes, there is Enum.IsDefined() to check if the value you want to convert exists in your enum.

@Kraang Prime 2015-07-08 04:50:23

Good answer. Just makes me wonder why this high level language requires so much for things that were naturally much simpler in predecessor languages. In Visual Basic 6, you could past the int value OR the enum. Comparing with other modern languages, even PHP allows for passing the int directly.

@Aidiakapi 2015-08-17 16:09:20

@JustinTConroy Except that it's not. When you call Parse, you trust the input value to be correct, and when it isn't, it's a bug in the code (and there's an exception as there should be). If you're dealing with user input, you should always call TryParse, because invalid input isn't exceptional. The article you linked mentions this in "the 99% use case for this method is transforming strings input by the user", that's the bug, the method isn't designed to handle user input, TryParse is.

@Justin T Conroy 2015-08-18 17:28:26

@Aidiakapi How often are you trying to parse strings to ints where you have total control of the value being passed for all eternity? ;-)

@Aidiakapi 2015-08-18 18:25:54

@JustinTConroy Any time you trust the input. One example could be with serialization or saving files. You can trust your file's format to be correct, if not, just throw an exception, because you're dealing with corrupt input anyways then. Most of the cases have to do with interoperability or compatibility. Any time you're communicating between programs using ints stored as strings, it's exceptional that miscommunication happens, and indicates a bug in the code.

@Craig Gjerdingen 2016-10-28 19:06:23

Here is a Fiddle or REPL to mess around with this example repl.it/EJCV/1

@abigblackman 2008-08-27 04:00:38

Take the following example:

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

@reza.cse08 2016-11-17 12:49:05

It can help you to convert any input data to user desired enum. Suppose you have an enum like below which by default int. Please add a Default value at first of your enum. Which is used at helpers medthod when there is no match found with input value.

public enum FriendType  
{
    Default,
    Audio,
    Video,
    Image
}

public static class EnumHelper<T>
{
    public static T ConvertToEnum(dynamic value)
    {
        var result = default(T);
        var tempType = 0;

        //see Note below
        if (value != null &&
            int.TryParse(value.ToString(), out  tempType) && 
            Enum.IsDefined(typeof(T), tempType))
        {
            result = (T)Enum.ToObject(typeof(T), tempType); 
        }
        return result;
    }
}

N.B: Here I try to parse value into int, because enum is by default int If you define enum like this which is byte type.

public enum MediaType : byte
{
    Default,
    Audio,
    Video,
    Image
} 

You need to change parsing at helper method from

int.TryParse(value.ToString(), out  tempType)

to

byte.TryParse(value.ToString(), out tempType)

I check my method for following inputs

EnumHelper<FriendType>.ConvertToEnum(null);
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("-1");
EnumHelper<FriendType>.ConvertToEnum("6");
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("2");
EnumHelper<FriendType>.ConvertToEnum(-1);
EnumHelper<FriendType>.ConvertToEnum(0);
EnumHelper<FriendType>.ConvertToEnum(1);
EnumHelper<FriendType>.ConvertToEnum(9);

sorry for my english

@Ted 2014-07-17 14:39:55

Slightly getting away from the original question, but I found an answer to Stack Overflow question Get int value from enum useful. Create a static class with public const int properties, allowing you to easily collect together a bunch of related int constants, and then not have to cast them to int when using them.

public static class Question
{
    public static readonly int Role = 2;
    public static readonly int ProjectFunding = 3;
    public static readonly int TotalEmployee = 4;
    public static readonly int NumberOfServers = 5;
    public static readonly int TopBusinessConcern = 6;
}

Obviously, some of the enum type functionality will be lost, but for storing a bunch of database id constants, it seems like a pretty tidy solution.

@Paul Richards 2014-09-01 07:41:58

enums superseded the use of integer constants like this since they provide more type safety

@Ted 2014-09-01 09:37:34

Paul, this is a method of collecting together related int constants (e.g. Database id constants) so they can be used directly without having to cast them to int every time they're used. Their type is integer, not for example, DatabaseIdsEnum.

@Thierry 2014-09-10 17:33:38

There is at least one situation that I have found in which enum type safety can be unintentionally bypassed.

@derHugo 2019-10-10 22:32:05

But enums also make sure the values are all unique, something this approach is also lacking

@Sébastien Duval 2013-02-21 15:22:07

For numeric values, this is safer as it will return an object no matter what:

public static class EnumEx
{
    static public bool TryConvert<T>(int value, out T result)
    {
        result = default(T);
        bool success = Enum.IsDefined(typeof(T), value);
        if (success)
        {
            result = (T)Enum.ToObject(typeof(T), value);
        }
        return success;
    }
}

@Daniel Fisher lennybacon 2015-03-30 10:00:59

This does not work with flag enums

@Abdul Munim 2011-11-11 13:27:35

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);
}

Usage:

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

OR

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

@BrainSlugs83 2013-06-04 20:56:56

For processing user input, it's probably a good idea to call the overload of Enum.Parse that is allows you to specify that the comparison NOT be case sensitive (i.e. a user typing "red" (lowercase) would crash the above code without this change.)

@nawfal 2013-06-08 21:41:41

Cool, except that it is not the question.

@BJury 2015-05-27 10:18:34

Handy, but the question specifically asks about ints.

@TruthOf42 2016-10-06 19:19:18

this also works if the string is an integer, e.g. "2"

@Justin 2016-10-18 15:03:33

This will throw an exception if enumString is null (had a similar issue yesterday). Consider using TryParse instead of Parse. TryParse will also check if T is an Enum Type

@Mr Anderson 2019-05-13 20:13:02

This type of extension method on System.String seems like namespace pollution

@Franki1986 2016-01-07 11:40:50

I don't know anymore where I get the part of this enum extension, but it is from stackoverflow. I am sorry for this! But I took this one and modified it for enums with Flags. For enums with Flags I did this:

  public static class Enum<T> where T : struct
  {
     private static readonly IEnumerable<T> All = Enum.GetValues(typeof (T)).Cast<T>();
     private static readonly Dictionary<int, T> Values = All.ToDictionary(k => Convert.ToInt32(k));

     public static T? CastOrNull(int value)
     {
        T foundValue;
        if (Values.TryGetValue(value, out foundValue))
        {
           return foundValue;
        }

        // For enums with Flags-Attribut.
        try
        {
           bool isFlag = typeof(T).GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
           if (isFlag)
           {
              int existingIntValue = 0;

              foreach (T t in Enum.GetValues(typeof(T)))
              {
                 if ((value & Convert.ToInt32(t)) > 0)
                 {
                    existingIntValue |= Convert.ToInt32(t);
                 }
              }
              if (existingIntValue == 0)
              {
                 return null;
              }

              return (T)(Enum.Parse(typeof(T), existingIntValue.ToString(), true));
           }
        }
        catch (Exception)
        {
           return null;
        }
        return null;
     }
  }

Example:

[Flags]
public enum PetType
{
  None = 0, Dog = 1, Cat = 2, Fish = 4, Bird = 8, Reptile = 16, Other = 32
};

integer values 
1=Dog;
13= Dog | Fish | Bird;
96= Other;
128= Null;

@Will Yu 2014-11-21 00:32:24

From a string: (Enum.Parse is out of Date, use Enum.TryParse)

enum Importance
{}

Importance importance;

if (Enum.TryParse(value, out importance))
{
}

@BJury 2015-05-27 10:13:30

The question specifically asks about integers.

@JeremyWeir 2016-02-10 05:37:55

Will Yu please edit your answer to let everyone know Enum.TryParse will work on a string of the value or name of the enum (I couldn't resist)

@huysentruitw 2018-01-29 12:20:05

Jeremy, Weir working on that (couldn't resist either).

@CZahrobsky 2014-07-30 20:02:52

This parses integers or strings to a target enum with partial matching in dot.NET 4.0 using generics like in Tawani's utility class above. I am using it to convert command-line switch variables which may be incomplete. Since an enum cannot be null, you should logically provide a default value. It can be called like this:

var result = EnumParser<MyEnum>.Parse(valueToParse, MyEnum.FirstValue);

Here's the code:

using System;

public class EnumParser<T> where T : struct
{
    public static T Parse(int toParse, T defaultVal)
    {
        return Parse(toParse + "", defaultVal);
    }
    public static T Parse(string toParse, T defaultVal) 
    {
        T enumVal = defaultVal;
        if (defaultVal is Enum && !String.IsNullOrEmpty(toParse))
        {
            int index;
            if (int.TryParse(toParse, out index))
            {
                Enum.TryParse(index + "", out enumVal);
            }
            else
            {
                if (!Enum.TryParse<T>(toParse + "", true, out enumVal))
                {
                    MatchPartialName(toParse, ref enumVal);
                }
            }
        }
        return enumVal;
    }

    public static void MatchPartialName(string toParse, ref T enumVal)
    {
        foreach (string member in enumVal.GetType().GetEnumNames())
        {
            if (member.ToLower().Contains(toParse.ToLower()))
            {
                if (Enum.TryParse<T>(member + "", out enumVal))
                {
                    break;
                }
            }
        }
    }
}

FYI: The question was about integers, which nobody mentioned will also explicitly convert in Enum.TryParse()

@LawMan 2014-07-02 14:58:49

In my case, I needed to return the enum from a WCF service. I also needed a friendly name, not just the enum.ToString().

Here's my WCF Class.

[DataContract]
public class EnumMember
{
    [DataMember]
    public string Description { get; set; }

    [DataMember]
    public int Value { get; set; }

    public static List<EnumMember> ConvertToList<T>()
    {
        Type type = typeof(T);

        if (!type.IsEnum)
        {
            throw new ArgumentException("T must be of type enumeration.");
        }

        var members = new List<EnumMember>();

        foreach (string item in System.Enum.GetNames(type))
        {
            var enumType = System.Enum.Parse(type, item);

            members.Add(
                new EnumMember() { Description = enumType.GetDescriptionValue(), Value = ((IConvertible)enumType).ToInt32(null) });
        }

        return members;
    }
}

Here's the Extension method that gets the Description from the Enum.

    public static string GetDescriptionValue<T>(this T source)
    {
        FieldInfo fileInfo = source.GetType().GetField(source.ToString());
        DescriptionAttribute[] attributes = (DescriptionAttribute[])fileInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);            

        if (attributes != null && attributes.Length > 0)
        {
            return attributes[0].Description;
        }
        else
        {
            return source.ToString();
        }
    }

Implementation:

return EnumMember.ConvertToList<YourType>();

@atlaste 2014-04-03 07:39:44

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();
}

@Rolan 2015-11-15 00:19:15

I realize this is an old post, but how do you gain this level of knowledge in c#? Is this from reading through the C# specification?

@atlaste 2015-11-15 11:38:42

@Rolan I sometimes wish more people would ask that. :-) To be honest I don't really know; I try to understand how things work and get information wherever I can get it. I did read the C# standard, but I also regularly decompile code with Reflector (I even look at the x86 assembler code a lot) and do tons of little experiments. Also, knowing about other languages helps in this case; I've been doing CS for about 30 years now, and at some point certain things become 'logical' - f.ex. an enum should integral types, because otherwise interop will break (or your performance will go down the drain).

@atlaste 2015-11-15 11:43:46

I believe the key to doing software engineering properly is knowing how stuff works. For me that means that if you write a piece of code, you know how it roughly translates to f.ex. processor operations and memory fetches / writes. If you ask how to get to that level, I'd suggest building a ton of small test cases, making them tougher as you go, try to predict the outcome every time, and test them afterwards (incl. decompilation, etc). After figuring out all the details and all the characteristics, you can check if you got it right in the (dull) standard. At least, that would be my approach.

@gravidThoughts 2016-08-11 17:04:35

Fantastic answer, thanks! In your last code sample, it throws an exception at runtime because o is an object. You can cast an int variable to a short as long as it falls within the short range.

@atlaste 2016-08-12 06:43:14

@gravidThoughts Thanks. Actually it's an unboxing operation, so it won't do any implicit conversions like the ones you describe. Casting is sometimes confusing in C# if you don't know the details... Anyhow, because int != short, it will throw (unboxing fails). If you do object o = (short)5;, it will work, because then the types will match. It's not about the range, it's really about the type.

@HeyJude 2018-01-04 11:27:48

@atlaste, if MyEnum derives (or is it?) from int, why assigning an int value to a MyEnum typed variable doesn't work without an explicit cast? Is it possible to somehow make the assignment work without an explicit cast?

@atlaste 2018-01-04 11:30:30

@HeyJude Well, that's simply because the C# dev team decided this was the right syntax. It basically avoids having enum's alive with undefined integer values (e.g. otherwise you can set any enum to any value). In other languages like C++ this is actually possible.

@Shivprasad Koirala 2014-02-05 12:15:25

enter image description here

To convert a string to ENUM or int to ENUM constant we need to use Enum.Parse function. Here is a youtube video https://www.youtube.com/watch?v=4nhx4VwdRDk which actually demonstrate's with string and the same applies for int.

The code goes as shown below where "red" is the string and "MyColors" is the color ENUM which has the color constants.

MyColors EnumColors = (MyColors)Enum.Parse(typeof(MyColors), "Red");

@gmail user 2014-01-08 15:18:34

Different ways to cast to and from Enum

enum orientation : byte
{
 north = 1,
 south = 2,
 east = 3,
 west = 4
}

class Program
{
  static void Main(string[] args)
  {
    orientation myDirection = orientation.north;
    Console.WriteLine(“myDirection = {0}”, myDirection); //output myDirection =north
    Console.WriteLine((byte)myDirection); //output 1

    string strDir = Convert.ToString(myDirection);
        Console.WriteLine(strDir); //output north

    string myString = “north”; //to convert string to Enum
    myDirection = (orientation)Enum.Parse(typeof(orientation),myString);


 }
}

@Ryan Russon 2011-11-01 14:58:49

If you're ready for the 4.0 .NET Framework, there's a new Enum.TryParse() function that's very useful and plays well with the [Flags] attribute. See Enum.TryParse Method (String, TEnum%)

@CodesInChaos 2011-11-01 15:08:35

That's useful when converting from a string. But not when converting from an int.

@L. D. 2010-07-02 14:41:41

Sometimes you have an object to the MyEnum type. Like

var MyEnumType = typeof(MyEnumType);

Then:

Enum.ToObject(typeof(MyEnum), 3)

@MSkuta 2011-10-21 10:05:43

I am using this piece of code to cast int to my enum:

if (typeof(YourEnum).IsEnumDefined(valueToCast)) return (YourEnum)valueToCast;
else { //handle it here, if its not defined }

I find it the best solution.

@Daniel Fisher lennybacon 2015-03-30 10:09:23

Does not work with flags enums

@orion elenzil 2015-11-20 00:50:52

this is good. i was surprised there's not an exception when casting an invalid value to an int-backed enum.

@Don Cheadle 2017-12-20 16:17:13

This actually is not so different than the top-rated answer. That answer also discusses using Enum.IsDefined after you've casted the string to the Enum type. So even if the string was casted without error, Enum.IsDefined will still catch it

@Tawani 2010-09-07 04:42:51

Below is a nice utility class for Enums

public static class EnumHelper
{
    public static int[] ToIntArray<T>(T[] value)
    {
        int[] result = new int[value.Length];
        for (int i = 0; i < value.Length; i++)
            result[i] = Convert.ToInt32(value[i]);
        return result;
    }

    public static T[] FromIntArray<T>(int[] value) 
    {
        T[] result = new T[value.Length];
        for (int i = 0; i < value.Length; i++)
            result[i] = (T)Enum.ToObject(typeof(T),value[i]);
        return result;
    }


    internal static T Parse<T>(string value, T defaultValue)
    {
        if (Enum.IsDefined(typeof(T), value))
            return (T) Enum.Parse(typeof (T), value);

        int num;
        if(int.TryParse(value,out num))
        {
            if (Enum.IsDefined(typeof(T), num))
                return (T)Enum.ToObject(typeof(T), num);
        }

        return defaultValue;
    }
}

@Matt Hamilton 2008-08-27 04:01:14

Just cast it:

MyEnum e = (MyEnum)3;

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

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

@dtroy 2009-07-31 04:49:58

Beware you can't use Enum.IsDefined if you use the Flags attribute and the value is a combination of flags for example: Keys.L | Keys.Control

@adrian 2013-12-04 11:26:37

Regarding Enum.IsDefined, be aware that it can be dangerous: msdn.microsoft.com/en-us/library/ms229025(VS.90).aspx

@Alexander 2014-04-23 16:06:30

On the other hand, if I validate the input based on the enum the library provides, before sending it to the library itself...

@Pap 2014-08-18 19:13:59

I prefer this definition: "Returns an indication whether a constant with a specified value exists in a specified enumeration" from MSDN

@Pap 2014-08-18 19:20:33

...Because your definition can be misleading, because you are saying: "...check if it's in range..." which implies within a range of numbers with starting and ending limits...

@daniloquio 2018-04-04 13:57:57

Note that an Enum's value is int by default, but that can be changed which may make the cast dangerous. Check @atlastes's answer.

@Michael Crenshaw 2018-11-01 17:42:47

@adrian can you provide a succinct example of a dangerous scenario? Having trouble wrapping my head around that doc.

@adrian 2018-11-12 22:43:12

@mac9416 I've tried to give a succinct example at gist.github.com/alowdon/f7354cda97bac70b44e1c04bc0991bcc - basically by using IsDefined to check input values, you leave yourself vulnerable to people adding new enum values later which would pass an IsDefined check (since the new value exists in the new code), but which might not work with the original code you wrote. It's therefore safer to explicitly specify the enum values that your code is able to handle.

Related Questions

Sponsored Content

27 Answered Questions

[SOLVED] How to enumerate an enum?

26 Answered Questions

[SOLVED] Do I cast the result of malloc?

  • 2009-03-03 10:13:02
  • Patrick McDonald
  • 212699 View
  • 2299 Score
  • 26 Answer
  • Tags:   c malloc casting

28 Answered Questions

[SOLVED] Get int value from enum in C#

  • 2009-06-03 06:46:39
  • jim
  • 1387768 View
  • 1667 Score
  • 28 Answer
  • Tags:   c# enums casting int

8 Answered Questions

11 Answered Questions

26 Answered Questions

[SOLVED] How to get an enum value from a string value in Java?

  • 2009-03-02 22:56:34
  • Malachi
  • 1045206 View
  • 1873 Score
  • 26 Answer
  • Tags:   java enums

14 Answered Questions

[SOLVED] Comparing Java enum members: == or equals()?

  • 2009-11-17 17:26:27
  • Matt Ball
  • 614366 View
  • 1619 Score
  • 14 Answer
  • Tags:   java enums

43 Answered Questions

[SOLVED] How can I represent an 'Enum' in Python?

Sponsored Content