C# int to enum conversion [duplicate]
Asked Answered
D

5

82

Possible Duplicate:
Cast int to enum in C#

If I have the following code:

enum foo : int
{
    option1 = 1,
    option2,
    ...
}

private foo convertIntToFoo(int value)
{
    // Convert int to respective Foo value or throw exception
}

What would the conversion code look like?

Declaration answered 2/2, 2009 at 11:30 Comment(2)
For a "checked" conversion, you'll need Enum.IsDefined. You may want to check out The ins and outs of C# enums, which describes this as well as other enum conversions.Inventor
Cast int to enum and vice versa in C#France
C
140

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.

Crissycrist answered 2/2, 2009 at 14:4 Comment(1)
Regarding strings - Enum.IsDefined compares value of type string against the enum Member Names. it compares value of type enumType (int) against the enum Member Values. So Enum.IsDefined(typeof(Foo), 1) = true but Enum.IsDefined(typeof(Foo), "1") = false. (msdn.microsoft.com/en-us/library/system.enum.isdefined.aspx)Balsa
C
18

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)

Colyer answered 2/2, 2009 at 11:32 Comment(3)
what if value is not defined??Guiscard
dittodhole: If value is not defined, it will still silently accept the value. I have no idea why they chose to design it this way.Ambitendency
And that's the reason any switch statement on an enum value should include a default that (when no other functionality makes sense) throws an exception...Eighteen
D
7

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 == default(TInput))
    {
        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);
}
Discerning answered 2/2, 2009 at 12:13 Comment(1)
I would prefer to change the statement if (value == null) to if (value == default(TInput)).Cheshire
A
5
if (Enum.IsDefined(typeof(foo), value))
{
   return (Foo)Enum.Parse(typeof(foo), value);
}

Hope this helps

Edit This answer got down voted as value in my example is a string, where as the question asked for an int. My applogies; the following should be a bit clearer :-)

Type fooType = typeof(foo);

if (Enum.IsDefined(fooType , value.ToString()))
{
   return (Foo)Enum.Parse(fooType , value.ToString());
}
Aceldama answered 2/2, 2009 at 11:47 Comment(2)
I don't think that this will compile. Enum.Parse() takes a string, while value should be an int based on the original question.Hhd
@Hhd - It's a snippet for a starting point so I doubt it does compile :-) This way you could also pass in "option1" as the value and it should parse it into the associated enum value.Aceldama
P
3

You don't need the inheritance. You can do:

(Foo)1 

it will work ;)

Presume answered 2/2, 2009 at 11:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.