Cast int to enum in C#


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



Answers


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



Just cast it:

MyEnum e = (MyEnum)3;

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

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



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



How do I convert an enum to a list in C#?

This will return an IEnumerable<SomeEnum> of all the values of an Enum.

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();

If you want that to be a List<SomeEnum>, just add .ToList() after .Cast<SomeEnum>().

To use the Cast function on an Array you need to have the System.Linq in your using section.




Much easier way:

Enum.GetValues(typeof(SomeEnum))
    .Cast<SomeEnum>()
    .Select(v => v.ToString())
    .ToList();



The short answer is, use:

(SomeEnum[])Enum.GetValues(typeof(SomeEnum))

If you need that for a local variable, it's var allSomeEnumValues = (SomeEnum[])Enum.GetValues(typeof(SomeEnum));.

Why is the syntax like this?!

The static method GetValues was introduced back in the old .NET 1.0 days. It returns a one-dimensional array of runtime type SomeEnum[]. But since it's a non-generic method (generics was not introduced until .NET 2.0), it can't declare its return type (compile-time return type) as such.

.NET arrays do have a kind of covariance, but because SomeEnum will be a value type, and because array type covariance does not work with value types, they couldn't even declare the return type as an object[] or Enum[]. (This is different from e.g. this overload of GetCustomAttributes from .NET 1.0 which has compile-time return type object[] but actually returns an array of type SomeAttribute[] where SomeAttribute is necessarily a reference type.)

Because of this, the .NET 1.0 method had to declare its return type as System.Array. But I guarantee you it is a SomeEnum[].

Everytime you call GetValues again with the same enum type, it will have to allocate a new array and copy the values into the new array. That's because arrays might be written to (modified) by the "consumer" of the method, so they have to make a new array to be sure the values are unchanged. .NET 1.0 didn't have good read-only collections.

If you need the list of all values many different places, consider calling GetValues just once and cache the result in read-only wrapper, for example like this:

public static readonly ReadOnlyCollection<SomeEnum> AllSomeEnumValues
    = Array.AsReadOnly((SomeEnum[])Enum.GetValues(typeof(SomeEnum)));

Then you can use AllSomeEnumValues many times, and the same collection can be safely reused.

Why is it bad to use .Cast<SomeEnum>()?

A lot of other answers use .Cast<SomeEnum>(). The problem with this is that it uses the non-generic IEnumerable implementation of the Array class. This should have involved boxing each of the values into an System.Object box, and then using the Cast<> method to unbox all those values again. Luckily the .Cast<> method seems to check the runtime type of its IEnumerable parameter (the this parameter) before it starts iterating through the collection, so it isn't that bad after all. It turns out .Cast<> lets the same array instance through.

If you follow it by .ToArray() or .ToList(), as in:

Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList() // DON'T do this

you have another problem: You create a new collection (array) when you call GetValues and then create yet a new collection (List<>) with the .ToList() call. So that's one (extra) redundant allocation of an entire collection to hold the values.




C# int to enum conversion

It's fine just to cast your int to Foo:

int i = 1;
Foo f = (Foo)i;

If you try to cast a value that's not defined it will still work. The only harm that may come from this is in how you use the value later on.

If you really want to make sure your value is defined in the enum, you can use Enum.IsDefined:

int i = 1;
if (Enum.IsDefined(typeof(Foo), i))
{
    Foo f = (Foo)i;
}
else
{
   // Throw exception, etc.
}

However, using IsDefined costs more than just casting. Which you use depends on your implemenation. You might consider restricting user input, or handling a default case when you use the enum.

Also note that you don't have to specify that your enum inherits from int; this is the default behavior.




I'm pretty sure you can do explicit casting here.

foo f = (foo)value;

So long as you say the enum inherits(?) from int, which you have.

enum foo : int

EDIT Yes it turns out that by default, an enums underlying type is int. You can however use any integral type except char.

You can also cast from a value that's not in the enum, producing an invalid enum. I suspect this works by just changing the type of the reference and not actually changing the value in memory.

enum (C# Reference)
Enumeration Types (C# Programming Guide)




Casting should be enough. If you're using C# 3.0 you can make a handy extension method to parse enum values:

public static TEnum ToEnum<TInput, TEnum>(this TInput value)
{
    Type type = typeof(TEnum);

    if (value == null)
    {
        throw new ArgumentException("Value is null or empty.", "value");
    }

    if (!type.IsEnum)
    {
        throw new ArgumentException("Enum expected.", "TEnum");
    }

    return (TEnum)Enum.Parse(type, value.ToString(), true);
}



Is it possible to cast integer to enum?

Yes, it's possible to cast Enum to int and vice versa, because every Enum is actually represented by an int per default. You should manually specify member values. By default it starts from 0 to N.

It's also possible to cast Enum to string and vice versa.

public enum MyEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

private static void Main(string[] args)
{
    int enumAsInt = (int)MyEnum.Value2; //enumAsInt == 2

    int myValueToCast = 3;
    string myValueAsString = "Value1";
    MyEnum myValueAsEnum = (MyEnum)myValueToCast;   // Will be Value3

    MyEnum myValueAsEnumFromString;
    if (Enum.TryParse<MyEnum>(myValueAsString, out myValueAsEnumFromString))
    {
        // Put logic here
        // myValueAsEnumFromString will be Value1
    }

    Console.ReadLine();
}



Yes it is possible. I use the following ENUM

public enum AccountTypes
{
  Proposed = 1,
  Open = 2
}

then when I call it I use this to get the value:

(int)AccountTypes.Open

And it will return the int value that I need which for the above will be 2.




From the C# 4.0 Specification:

1.10 Enums

Enum values can be converted to integral values and vice versa using type casts. For example

int i = (int)Color.Blue;      // int i = 2;
Color c = (Color)2;               // Color c = Color.Blue;

One additional thing to be aware of is that you are permitted to cast any integral value in the range of the enum's underlying type (by default that's int), even if that value doesn't map to one of the names in the enum declaration. From 1.10 Enums:

The set of values that an enum type can take on is not limited by its enum members. In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type.

So, the following is also permitted with the enum in your example:

det.documentStatus = (detallistaDocumentStatus) 42;

even though there's no enum name that has the value 42.