Get int value from enum in C#

1,979,128

Solution 1

Just cast the enum, e.g.

int something = (int) Question.Role;

The above will work for the vast majority of enums you see in the wild, as the default underlying type for an enum is int.

However, as cecilphillip points out, enums can have different underlying types. If an enum is declared as a uint, long, or ulong, it should be cast to the type of the enum; e.g. for

enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};

you should use

long something = (long)StarsInMilkyWay.Wolf424B;

Solution 2

Since Enums can be any integral type (byte, int, short, etc.), a more robust way to get the underlying integral value of the enum would be to make use of the GetTypeCode method in conjunction with the Convert class:

enum Sides {
    Left, Right, Top, Bottom
}
Sides side = Sides.Bottom;

object val = Convert.ChangeType(side, side.GetTypeCode());
Console.WriteLine(val);

This should work regardless of the underlying integral type.

Solution 3

Declare it as a static class having public constants:

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

And then you can reference it as Question.Role, and it always evaluates to an int or whatever you define it as.

Solution 4

On a related note, if you want to get the int value from System.Enum, then given e here:

Enum e = Question.Role;

You can use:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

The last two are plain ugly. I prefer the first one.

Solution 5

Question question = Question.Role;
int value = (int) question;

Will result in value == 2.

Share:
1,979,128
Simon Buchholz
Author by

Simon Buchholz

I type fast, attend meetings, drink coffee, nod my head vigorously and enjoy telling others what to do.

Updated on July 14, 2022

Comments

  • Simon Buchholz
    Simon Buchholz almost 2 years

    I have a class called Questions (plural). In this class there is an enum called Question (singular) which looks like this.

    public enum Question
    {
        Role = 2,
        ProjectFunding = 3,
        TotalEmployee = 4,
        NumberOfServers = 5,
        TopBusinessConcern = 6
    }
    

    In the Questions class I have a get(int foo) function that returns a Questions object for that foo. Is there an easy way to get the integer value off the enum so I can do something like this Questions.Get(Question.Role)?

    • nawfal
      nawfal almost 11 years
      For the other way around: cast-int-to-enum-in-c-sharp.
    • Joe
      Joe over 7 years
      I know I'm late to the party, but instead of defining your method as get(int foo) you can define it as get(Question foo) then do your casting inside the method, the you can call your method as Questions.Get(Question.Role)
    • گلی
      گلی almost 3 years
      try this: int int_Choose = (int) Question.Role;
  • Simon Buchholz
    Simon Buchholz almost 15 years
    So something like this Questions.Get(Convert.ToInt16(Question.Applications))
  • Marc Gravell
    Marc Gravell almost 15 years
    You can simply cast in either direction; the only thing to watch is that enums don't enforce anything (the enum value could be 288, even though no Question exists with that number)
  • Guffa
    Guffa almost 15 years
    @jim: No, just cast the value: Questions.Get((int)Question.Applications);
  • mqp
    mqp almost 15 years
    Nitpick: this enum is already an int. Other enums might be different types -- try "enum SmallEnum : byte { A, B, C }"
  • Michael Petrotta
    Michael Petrotta almost 15 years
    Absolutely true. C# reference: "Every enumeration type has an underlying type, which can be any integral type except char."
  • aboy021
    aboy021 almost 13 years
    This technique proved its worth to me when dealing with a generic type where T:enum (actually T:struct, IConvertible but that's a different story).
  • Jaider
    Jaider almost 12 years
    @Harry it isn't true. You can create Enumeration without casting, it is not required. and I only assign number in special cases, most of the time, I leave it as default value. but you can do enum Test { Item = 1 } and see that 1 == (int)Test.Item is equal.
  • Sinthia V
    Sinthia V almost 12 years
    @Jaider (int)Test.Item That is a cast! () is the explicit cast operator.
  • Paul Ridgway
    Paul Ridgway over 11 years
    @Sinthia V he said you can create it without casting, which is correct
  • Mark Lakata
    Mark Lakata over 11 years
    How would you modify this to print out the hexadecimal value of side? This example shows the decimal value. The problem is that var is of type object, so you need to unbox it and it gets messier than I would like.
  • Benjamin Gruenbaum
    Benjamin Gruenbaum over 11 years
    Bronek, what you did is make up uninformative syntax through a (non generic btw) extension method that actually takes longer to write. I fail to see how it is better than the original solution by Tetraneutron. Let us not make this into a chat, help is always welcome in stackoverflow and everyone here is here to help. Please take my comment as constructive criticism.
  • Bronek
    Bronek over 11 years
    Benjamin,first of all,why did you delete my comment?I don't understand your decisions-maybe somebody else through the community would agree with my comment.Secondly,my solution wraps Tetraneutron's one and accurately it is easier and less writing because an extension method is suggested by IntelliSense.So I think your decision is not impartial and representative.I see many similar answering on Stack and it is OK.Anyway I use my solution and maybe there are some people would choose my solution in the future,but these negative points make it harder to find.Most of all it is correct and not copy.
  • CAD bloke
    CAD bloke almost 11 years
    I'd use static readonly int because constants are compiled into their hard values. See stackoverflow.com/a/755693/492
  • user692942
    user692942 almost 11 years
    I guess it's the trade off between explicit cast and the code you have to write to circumvent it. Still love the implementation just wish it wasn't so lengthy. +1
  • Benjamin Gruenbaum
    Benjamin Gruenbaum almost 11 years
    @Bronek If you don't ping me I get no indication that you replied. I did not delete your comment I do not have the ability or want to do so. Likely a mod came by and deleted it - you're welcome to flag it for moderator attention and ask why or better yet - ask on Meta Stack Overflow. I have an opinion about your solution from a programming stand point which is perfectly in my right - this is what comments are for to begin with, no need to take it personal.
  • quaylar
    quaylar over 10 years
    If the underlying type for enum Question was not int but long this cast will truncate Roles integral value!
  • thgc
    thgc about 10 years
    This solution actually doesn't provide the real benefit of strongly typed enums. If I only wanted to pass a GameState-enum-parameter to a specific method for example, the compiler shouldn't allow me to pass any int-variable as a parameter.
  • theLaw
    theLaw almost 10 years
    If you want to convert to int try (in case of an enum Sides : int) [...] object val = Convert.ChangeType(side, typeof(int)); [...]
  • NickG
    NickG almost 10 years
    You should always explicity set the int value of each enum option as the assigned number is not guaranteed and can vary by system. If you then build the DLL on another system, the enum values can change. This caused me a nightmare of a problem in the past when the enum values had to correspond with the values a database.
  • blockloop
    blockloop over 9 years
    @CADBloke which is precisely why you would use const and not static readonly because every time you compare static readonly you're making a method call to get the value of the variable whereas with a const you're comparing two value types directly.
  • CAD bloke
    CAD bloke over 9 years
    @brettof86 Yes, a const would be faster, if the compilation limitation will never be problem then it's all good.
  • surfer01
    surfer01 over 9 years
    Possibly because doing (int)customFlag is less typing all around and does more or less the same thing?
  • Matt
    Matt about 9 years
    @NickG can I ask what caused the assigned numbers to change? I ask because I've never heard of this and have always relied on the documented behaviour - msdn.microsoft.com/en-us/library/sbbt4032.aspx "By default, the first enumerator has the value 0"
  • NickG
    NickG about 9 years
    @TimAbell All I can really say is that we found that dynamically compiled aspx pages (where you have to deploy the .cs files to the live server) were assigning the integers differently to each value. That meant that serialised objects one one machine, were deserialising with different values on a different machine and effectively getting corrupted (causing hours of confusion). We raised it with MS and I seem to recall they said that the autogenerated integers were not guaranteed to be the same when built across different framework versions.
  • NickG
    NickG about 9 years
    @TimAbell On a separate occasion, a developer deleted an obsolete/unused Enum value causing all other values in the sequence to be out by one. As such, our coding standards now require that IDs are always specified explicitly, otherwise adding/deleting or even auto-formatting the code (e.g. sorting alphabetically) will change all the values causing data corruption. I would strongly advise anyone to specify all Enum integers explicitly. This is ultra-important if they correlate to externally (database) stored values.
  • Matt
    Matt about 9 years
    Thanks for the info @NickG, that's some really valuable context. So if I can summarise: as soon as anything external to your program has knowledge of the integer values then any changes in them become a real problem and having explicit numbering makes subsequent breakage less likely.
  • NickG
    NickG about 9 years
    Absolutely. Or if you suspect for any reason you might have to modify the enum values (including deleting or even reordering the code). I'd just always do it as there's no reason not to.
  • Matt
    Matt about 9 years
    I'd say "always" is overkill (the only absolute rule is there are no absolutes). If your enum never ventures outside the confines of your program then you're adding a minor overhead to editing the enum list by forcing people to figure out what the compiler would have done for you. Whether you care about modifications depends on where they're used. imho.
  • El Mac
    El Mac about 9 years
    @PaulRidgway that wasn't the question.
  • Zack
    Zack about 9 years
    @CADbloke What do you mean by "compilation limitation" here? Do you use static readonly int because you are loading the values dynamically from a settings file or something? I think if you are using this static class in place of an enum that it should be a const because the values will not change.
  • CAD bloke
    CAD bloke about 9 years
    @Zack I didn't explain that very well, by compilation limitation I mean that the value is hard-coded when you compile it so any change to that value would require that all assemblies using it need to be recompiled. I'm inclined to agree with you about usage because changing the values would have far-reaching implications.
  • percebus
    percebus over 8 years
    When you accept an Enum as a parameter, you know is only a fixed number of possible integral values you can get. On the other hand, if you take simply an int, then you have to validate if that int is within the accepted values., thus complicating the code. You can always override your signatures like ``` public void MyMethod(int x) { // do something with x } public void MyMethod(Enum x) { this.MyMethod((int) x); } ````
  • Jeppe Stig Nielsen
    Jeppe Stig Nielsen over 8 years
    Getting a boxed (object) integer type is not very useful when you do not know the width of the integer type at compile-time! If you just want to write out the numerical value, use Sides side = Sides.Bottom; Console.WriteLine("{0:D}", side);. If you want a reference to the string, that is string sideStr = side.ToString("D");. And to answer the comment by @MarkLakata, just use X instead of D, that is Console.WriteLine("{0:X}", side) or side.ToString("X"). A lower-case x gives hexadecimal with lower-case digits a through f.
  • David Mårtensson
    David Mårtensson about 8 years
    The problem with this solution (we use it our self) is that it will not be obvious from the method signature what constants to use and there will be no compile time checking of valid entries. But aside from that this works very good.
  • James Haug
    James Haug over 7 years
    I've used several different type of classes structured similar to this. I find they work wonders when trying to follow the "don't let me be an idiot later" methodology.
  • Timothy Gonzalez
    Timothy Gonzalez over 7 years
    I was looking for an alternative, but this looks to be the best option with all the complexity, as pointed out in the top answers, involved in converting an enum to int.
  • Timothy Gonzalez
    Timothy Gonzalez over 7 years
    Can something that is a Raj be also be a Rahul or a Priyanka? Your values conflict and should double to be unique e.g. 0, 1, 2, 4, 8, etc. This is my core concern with enums.
  • quemeful
    quemeful about 7 years
    In my opinion this answer is the best, for development speed and readability. The compilation limitation, if any, is totally worth it.
  • MIKE
    MIKE over 6 years
    clever! casting each enum is so ugly to look at
  • Neil Busse
    Neil Busse about 6 years
    I would shy away from using Long and Enum, but there might be a specific use case where that would actually make sense.
  • ThanhLD
    ThanhLD over 5 years
    GetHashCode is one way to get value from Enum common mask
  • Greg
    Greg over 5 years
    Unfortunately, this approach gives poor performance the more you use it. I tried it in some code of mine, and as time went on, my application got slower and slower, with less and less CPU usage. This implied that the threads were waiting on something - I'm assuming some kind of garbage collection, possibly due to boxing the enum parameter to ToInt32(). By switching to a simple int.Parse(), I was able to eliminate this poor performance completely, and the performance stayed the same no matter how long the code ran.
  • Johan B
    Johan B almost 5 years
    The second one is the fastest though.
  • Maurício
    Maurício over 4 years
    This is only true if the enum fits inside an int of course, as GetHashCode returns an integer.
  • derHugo
    derHugo over 4 years
    @TimothyGonzalez actually enums simply count 1 up if you don't explicitly specify their value ;)
  • Timothy Gonzalez
    Timothy Gonzalez over 4 years
    @derHugo that depends if you assume the numerical values to be base 10 or base 2.
  • derHugo
    derHugo over 4 years
    @TimothyGonzalez well there is not much to assume ... I just pointed out that by default they do just count up 1 in int except you explicitly define otherwise
  • Sollace
    Sollace over 4 years
    As someone who is used to using Mixins in Minecraft modding, the second seems like the obvious winner.
  • Peter Mortensen
    Peter Mortensen over 4 years
    Re "Maybe I missed it, but has anyone tried a simple generic extension method?": SixOThree said "Use an extension method instead" and Bronek said "You can do this by implementing an extension method to your defined enum type".
  • Peter Mortensen
    Peter Mortensen over 4 years
    An explanation of the sample code would be in order (by editing your answer, not here in comments).
  • Chad Grant
    Chad Grant over 4 years
    zero is generally reserved for unset / unkown state in enums, unusual to define it like that
  • Chad Grant
    Chad Grant over 4 years
    This has nothing to do with enums / enumerations
  • Chad Grant
    Chad Grant over 4 years
    please no, you could do all this in one line Convert.Changetype(e, e.GetTypeCode()) and get an object back, no need for dynamics or an extension method
  • AnorZaken
    AnorZaken about 4 years
    Note that this is only "legit" for bool*, byte, ushort, int, and uint**. The GetHashCode for other types modifies the value, e.g. does some bitshifts and xors. (* 1 / 0, **casted to int of course). But all in all just don't do this unless it's your own private code.
  • Jeff
    Jeff about 4 years
    I will disagree with using Convert. Just using a cast would be easier. My intent was to be able to convert any enum to it's value without using a cast. This allows the changing of the enum type wihtout having to change all of the associated casts - but when does this happen?. The extension method works correctly. However, I am having an issue with it in that, since it is dynamic, the complier cannot type check (for the entire statement apparently) which means type checking occurs when run - not a good solution. I think I'll go back to casts.
  • Chad Grant
    Chad Grant about 4 years
    I didn't say use it over cast, just that this code is nonsensical and accomplishing nothing, actually makes the problem worse. I would recommend removing this solution
  • Felix Keil
    Felix Keil about 4 years
    @NeilBusse Flagged enums maybe
  • andreyk2 Hohlov
    andreyk2 Hohlov over 3 years
    And the 5th option (as the most answers says) is: int i = (int)e; (without casting to object first)
  • nawfal
    nawfal over 3 years
    @andreyk2Hohlov Cannot convert type 'System.Enum' to 'int'
  • Andrew Chaa
    Andrew Chaa over 3 years
    This was the best solution for my use case, as my enums were mix of int and long values
  • Sarasjd
    Sarasjd about 3 years
    this one was best useful for me
  • Chris Catignani
    Chris Catignani about 3 years
    I like the constants for Case usage.
  • JohnLBevan
    JohnLBevan almost 2 years
    ps. Those who like this approach may be interested in github.com/ardalis/SmartEnum; a generic class aimed at giving enum like functionality to classes defined in the above way.