2314

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

jim
  • 26,598
  • 13
  • 51
  • 66
  • 47
    For the other way around: [cast-int-to-enum-in-c-sharp](http://stackoverflow.com/questions/29482/cast-int-to-enum-in-c-sharp). – nawfal Jun 09 '13 at 11:54
  • 16
    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)` – Joe Feb 07 '17 at 15:10
  • 1
    try this: int int_Choose = (int) Question.Role; – گلی Jul 18 '21 at 07:35
  • [See what you an do with enum types](https://stackoverflow.com/a/16039343/380384) – John Alexiou Aug 27 '23 at 00:18

31 Answers31

2914

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;
Sae1962
  • 1,122
  • 15
  • 31
Tetraneutron
  • 32,841
  • 3
  • 25
  • 21
  • 28
    @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. – Jaider Jun 28 '12 at 20:47
  • 52
    @Jaider `(int)Test.Item` That is a cast! () is the explicit cast operator. – Sinthia V Jul 26 '12 at 19:02
  • 58
    @Sinthia V he said you can *create* it without casting, which is correct – Paul Ridgway Aug 17 '12 at 18:30
  • 10
    If the underlying type for `enum Question` was not `int` but `long` this cast will truncate `Role`s integral value! – quaylar Oct 29 '13 at 16:14
  • @PaulRidgway that wasn't the question. – El Mac Apr 08 '15 at 09:19
  • 4
    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); } ```` – percebus Aug 18 '15 at 16:52
  • 1
    I would shy away from using Long and Enum, but there might be a specific use case where that would actually make sense. – Neil Busse Feb 09 '18 at 17:52
  • 2
    @NeilBusse Flagged enums maybe – Felix Keil Mar 11 '20 at 06:22
  • @percebus An `enum` type does not validate its values. An `enum` with `int` as its underlying type has 2^32 possible values. `Question q = (Question)(-17);` is totally valid. – Kris Vandermotten Mar 06 '23 at 10:08
378

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.

Sae1962
  • 1,122
  • 15
  • 31
cecilphillip
  • 11,446
  • 4
  • 36
  • 40
  • 49
    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). – aboy021 Jul 05 '11 at 23:20
  • 4
    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. – Mark Lakata Nov 09 '12 at 02:15
  • 3
    If you want to convert to int try (in case of an enum Sides : int) [...] object val = Convert.ChangeType(side, typeof(int)); [...] – theLaw Jun 09 '14 at 16:05
  • 1
    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. – NickG Aug 06 '14 at 09:58
  • @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 - https://msdn.microsoft.com/en-us/library/sbbt4032.aspx "By default, the first enumerator has the value 0" – Tim Abell Mar 23 '15 at 20:24
  • 6
    @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 Mar 24 '15 at 09:42
  • 12
    @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. – NickG Mar 24 '15 at 09:46
  • 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. – Tim Abell Mar 24 '15 at 13:30
  • 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. – NickG Mar 24 '15 at 13:32
  • 1
    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. – Tim Abell Mar 24 '15 at 13:57
  • 1
    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`. – Jeppe Stig Nielsen Oct 14 '15 at 19:06
225

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.

Sae1962
  • 1,122
  • 15
  • 31
PablosBicicleta
  • 2,437
  • 1
  • 13
  • 2
  • 38
    I'd use `static readonly int` because constants are compiled into their hard values. See http://stackoverflow.com/a/755693/492 – CAD bloke May 15 '13 at 23:16
  • 111
    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. – gchbib Apr 12 '14 at 18:24
  • 16
    @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. – blockloop Aug 14 '14 at 17:11
  • 5
    @brettof86 Yes, a const would be faster, if the compilation limitation will never be problem then it's all good. – CAD bloke Aug 15 '14 at 10:57
  • @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. – Zack Apr 22 '15 at 14:05
  • 6
    @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. – CAD bloke Apr 22 '15 at 21:53
  • 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. – David Mårtensson Mar 16 '16 at 13:53
  • 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 Nov 14 '16 at 20:59
  • In my opinion this answer is the best, for development speed and readability. The compilation limitation, if any, is totally worth it. – quemeful Feb 09 '17 at 16:29
  • 1
    clever! casting each enum is so ugly to look at – MIKE Feb 01 '18 at 02:21
  • This has nothing to do with enums / enumerations – Chad Grant Dec 27 '19 at 19:03
  • I like the constants for Case usage. – Chris Catignani Mar 25 '21 at 17:50
121

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.

ErikE
  • 48,881
  • 23
  • 151
  • 196
nawfal
  • 70,104
  • 56
  • 326
  • 368
111
Question question = Question.Role;
int value = (int) question;

Will result in value == 2.

jerryjvl
  • 19,723
  • 7
  • 40
  • 55
  • 4
    So something like this Questions.Get(Convert.ToInt16(Question.Applications)) – jim Jun 03 '09 at 06:51
  • 10
    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) – Marc Gravell Jun 03 '09 at 06:54
  • 3
    @jim: No, just cast the value: Questions.Get((int)Question.Applications); – Guffa Jun 03 '09 at 06:55
62

Example:

public enum EmpNo
{
    Raj = 1,
    Rahul,
    Priyanka
}

And in the code behind to get the enum value:

int setempNo = (int)EmpNo.Raj; // This will give setempNo = 1

or

int setempNo = (int)EmpNo.Rahul; // This will give setempNo = 2

Enums will increment by 1, and you can set the start value. If you don't set the start value it will be assigned as 0 initially.

  • 1
    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. – Timothy Gonzalez Nov 14 '16 at 21:58
  • 1
    @TimothyGonzalez actually enums simply count 1 up if you don't explicitly specify their value ;) – derHugo Oct 10 '19 at 22:30
  • 1
    @derHugo that depends if you assume the numerical values to be base 10 or base 2. – Timothy Gonzalez Oct 11 '19 at 14:57
  • 4
    @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 – derHugo Oct 11 '19 at 14:59
49

It's easier than you think - an enum is already an int. It just needs to be reminded:

int y = (int)Question.Role;
Console.WriteLine(y); // Prints 2
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
  • 17
    Nitpick: *this* enum is already an int. Other enums might be different types -- try "enum SmallEnum : byte { A, B, C }" – mqp Jun 03 '09 at 06:56
  • 11
    Absolutely true. C# reference: "Every enumeration type has an underlying type, which can be any integral type except char." – Michael Petrotta Jun 03 '09 at 06:59
35

I have recently converted away from using enums in my code in favour of instead using classes with protected constructors and predefined static instances (thanks to Roelof - C# Ensure Valid Enum Values - Futureproof Method).

In light of that, below's how I'd now approach this issue (including implicit conversion to/from int).

public class Question
{
    // Attributes
    protected int index;
    protected string name;
    // Go with a dictionary to enforce unique index
    //protected static readonly ICollection<Question> values = new Collection<Question>();
    protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>();

    // Define the "enum" values
    public static readonly Question Role = new Question(2,"Role");
    public static readonly Question ProjectFunding = new Question(3, "Project Funding");
    public static readonly Question TotalEmployee = new Question(4, "Total Employee");
    public static readonly Question NumberOfServers = new Question(5, "Number of Servers");
    public static readonly Question TopBusinessConcern = new Question(6, "Top Business Concern");

    // Constructors
    protected Question(int index, string name)
    {
        this.index = index;
        this.name = name;
        values.Add(index, this);
    }

    // Easy int conversion
    public static implicit operator int(Question question) =>
        question.index; //nb: if question is null this will return a null pointer exception

    public static implicit operator Question(int index) =>        
        values.TryGetValue(index, out var question) ? question : null;

    // Easy string conversion (also update ToString for the same effect)
    public override string ToString() =>
        this.name;

    public static implicit operator string(Question question) =>
        question?.ToString();

    public static implicit operator Question(string name) =>
        name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase));


    // If you specifically want a Get(int x) function (though not required given the implicit converstion)
    public Question Get(int foo) =>
        foo; //(implicit conversion will take care of the conversion for you)
}

The advantage of this approach is you get everything you would have from the enum, but your code's now much more flexible, so should you need to perform different actions based on the value of Question, you can put logic into Question itself (i.e. in the preferred OO fashion) as opposed to putting lots of case statements throughout your code to tackle each scenario.


NB: Answer updated 2018-04-27 to make use of C# 6 features; i.e. declaration expressions and lambda expression body definitions. See revision history for original code. This has the benefit of making the definition a little less verbose; which had been one of the main complaints about this answer's approach.

JohnLBevan
  • 22,735
  • 13
  • 96
  • 178
  • 2
    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 – user692942 Aug 02 '13 at 10:40
  • 4
    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. – James Haug Sep 08 '16 at 16:13
  • ps. Those who like this approach may be interested in https://github.com/ardalis/SmartEnum; a generic class aimed at giving enum like functionality to classes defined in the above way. – JohnLBevan Jun 01 '22 at 19:42
23

If you want to get an integer for the enum value that is stored in a variable, for which the type would be Question, to use for example in a method, you can simply do this I wrote in this example:

enum Talen
{
    Engels = 1, Italiaans = 2, Portugees = 3, Nederlands = 4, Duits = 5, Dens = 6
}

Talen Geselecteerd;    

public void Form1()
{
    InitializeComponent()
    Geselecteerd = Talen.Nederlands;
}

// You can use the Enum type as a parameter, so any enumeration from any enumerator can be used as parameter
void VeranderenTitel(Enum e)
{
    this.Text = Convert.ToInt32(e).ToString();
}

This will change the window title to 4, because the variable Geselecteerd is Talen.Nederlands. If I change it to Talen.Portugees and call the method again, the text will change to 3.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 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. – Greg Feb 04 '19 at 18:38
21

Use an extension method instead:

public static class ExtensionMethods
{
    public static int IntValue(this Enum argEnum)
    {
        return Convert.ToInt32(argEnum);
    }
}

And the usage is slightly prettier:

var intValue = Question.Role.IntValue();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SixOThree
  • 745
  • 1
  • 9
  • 21
19

One more way to do it:

Console.WriteLine("Name: {0}, Value: {0:D}", Question.Role);

It will result in:

Name: Role, Value: 2
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
plavozont
  • 807
  • 9
  • 17
17

To ensure an enum value exists and then parse it, you can also do the following.

// Fake Day of Week
string strDOWFake = "SuperDay";

// Real Day of Week
string strDOWReal = "Friday";

// Will hold which ever is the real DOW.
DayOfWeek enmDOW;

// See if fake DOW is defined in the DayOfWeek enumeration.
if (Enum.IsDefined(typeof(DayOfWeek), strDOWFake))
{
    // This will never be reached since "SuperDay"
    // doesn't exist in the DayOfWeek enumeration.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWFake);
}
// See if real DOW is defined in the DayOfWeek enumeration.
else if (Enum.IsDefined(typeof(DayOfWeek), strDOWReal))
{
    // This will parse the string into it's corresponding DOW enum object.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWReal);
}

// Can now use the DOW enum object.
Console.Write("Today is " + enmDOW.ToString() + ".");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nathon
  • 173
  • 1
  • 8
15
public enum QuestionType
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

...is a fine declaration.

You do have to cast the result to int like so:

int Question = (int)QuestionType.Role

Otherwise, the type is still QuestionType.

This level of strictness is the C# way.

One alternative is to use a class declaration instead:

public class QuestionType
{
    public static int Role = 2,
    public static int ProjectFunding = 3,
    public static int TotalEmployee = 4,
    public static int NumberOfServers = 5,
    public static int TopBusinessConcern = 6
}

It's less elegant to declare, but you don't need to cast it in code:

int Question = QuestionType.Role

Alternatively, you may feel more comfortable with Visual Basic, which caters for this type of expectation in many areas.

WonderWorker
  • 8,539
  • 4
  • 63
  • 74
15

Use:

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

It will result in value == 2.

This is only true if the enum fits inside an int.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
GinCanhViet
  • 353
  • 5
  • 13
  • 2
    This is only true if the enum fits inside an `int` of course, as `GetHashCode` returns an integer. – RB. Aug 14 '19 at 14:59
14

Maybe I missed it, but has anyone tried a simple generic extension method?

This works great for me. You can avoid the type cast in your API this way but ultimately it results in a change type operation. This is a good case for programming Roslyn to have the compiler make a GetValue<T> method for you.

    public static void Main()
    {
        int test = MyCSharpWrapperMethod(TestEnum.Test1);

        Debug.Assert(test == 1);
    }

    public static int MyCSharpWrapperMethod(TestEnum customFlag)
    {
        return MyCPlusPlusMethod(customFlag.GetValue<int>());
    }

    public static int MyCPlusPlusMethod(int customFlag)
    {
        // Pretend you made a PInvoke or COM+ call to C++ method that require an integer
        return customFlag;
    }

    public enum TestEnum
    {
        Test1 = 1,
        Test2 = 2,
        Test3 = 3
    }
}

public static class EnumExtensions
{
    public static T GetValue<T>(this Enum enumeration)
    {
        T result = default(T);

        try
        {
            result = (T)Convert.ChangeType(enumeration, typeof(T));
        }
        catch (Exception ex)
        {
            Debug.Assert(false);
            Debug.WriteLine(ex);
        }

        return result;
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Doug
  • 215
  • 2
  • 6
  • Possibly because doing (int)customFlag is less typing all around and does more or less the same thing? – Tim Keating Nov 11 '14 at 17:32
  • Re *"Maybe I missed it, but has anyone tried a simple generic **extension method**?"*: [SixOThree said](https://stackoverflow.com/questions/943398/get-int-value-from-enum-in-c-sharp/23190087#23190087) *"Use an **extension method** instead"* and [Bronek said](https://stackoverflow.com/questions/943398/get-int-value-from-enum-in-c-sharp/13792371#13792371) *"You can do this by implementing an **extension method** to your defined enum type"*. – Peter Mortensen Dec 08 '19 at 17:27
13
int number = Question.Role.GetHashCode();

number should have the value 2.

JaimeArmenta
  • 139
  • 1
  • 4
  • GetHashCode is one way to get value from Enum common mask – ThanhLD Nov 09 '18 at 04:08
  • 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. – AnorZaken Feb 18 '20 at 13:57
12

You can do this by implementing an extension method to your defined enum type:

public static class MyExtensions
{
    public static int getNumberValue(this Question questionThis)
    {
        return (int)questionThis;
    }
}

This simplifies getting the int value of the current enum value:

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

or

int value = Question.Role.getNumberValue();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bronek
  • 10,722
  • 2
  • 45
  • 46
  • 7
    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. – Benjamin Gruenbaum Dec 10 '12 at 00:28
  • 3
    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. – Bronek Dec 10 '12 at 03:20
  • 4
    @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]. 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. – Benjamin Gruenbaum Aug 07 '13 at 14:45
12
public enum Suit : int
{
    Spades = 0,
    Hearts = 1,
    Clubs = 2,
    Diamonds = 3
}

Console.WriteLine((int)(Suit)Enum.Parse(typeof(Suit), "Clubs"));

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

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

if (typeof(Suit).IsEnumDefined("Spades"))
{
    var res = (int)(Suit)Enum.Parse(typeof(Suit), "Spades");
    Console.Out.WriteLine("{0}", res);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gauravsa
  • 6,330
  • 2
  • 21
  • 30
  • An explanation of the sample code would be in order (by [editing your answer](https://stackoverflow.com/posts/51551978/edit), not here in comments). – Peter Mortensen Dec 08 '19 at 17:42
  • zero is generally reserved for unset / unkown state in enums, unusual to define it like that – Chad Grant Dec 27 '19 at 18:59
6

Since enums can be declared with multiple primitive types, a generic extension method to cast any enum type can be useful.

enum Box
{
    HEIGHT,
    WIDTH,
    DEPTH
}

public static void UseEnum()
{
    int height = Box.HEIGHT.GetEnumValue<int>();
    int width = Box.WIDTH.GetEnumValue<int>();
    int depth = Box.DEPTH.GetEnumValue<int>();
}

public static T GetEnumValue<T>(this object e) => (T)e;
Ashish Kamble
  • 2,555
  • 3
  • 21
  • 29
6

You should have used Type Casting as we can use in any other language.

If your enum is like this-

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

And you need to cast to an int, then do this-

Question q = Question.Role;
.............
.............
int something = (int) q;

Re-

In C#, there are two types of casting:

  • Implicit Casting (automatically) - converting a smaller type to a larger type size like-

char -> int -> long -> float -> double

  • Explicit Casting (manually) - converting a larger type to a smaller size type like-

double -> float -> long -> int -> char

More can be found in here.

Abrar Jahin
  • 13,970
  • 24
  • 112
  • 161
5

The easiest solution I can think of is overloading the Get(int) method like this:

[modifiers] Questions Get(Question q)
{
    return Get((int)q);
}

where [modifiers] can generally be same as for the Get(int) method. If you can't edit the Questions class or for some reason don't want to, you can overload the method by writing an extension:

public static class Extensions
{
    public static Questions Get(this Questions qs, Question q)
    {
        return qs.Get((int)q);
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Grx70
  • 10,041
  • 1
  • 40
  • 55
5

My favourite hack with int or smaller enums:

GetHashCode();

For an enum

public enum Test
{
    Min = Int32.MinValue,
    One = 1,
    Max = Int32.MaxValue,
}

This,

var values = Enum.GetValues(typeof(Test));

foreach (var val in values)
{
    Console.WriteLine(val.GetHashCode());
    Console.WriteLine(((int)val));
    Console.WriteLine(val);
}

outputs

one
1
1
max
2147483647
2147483647
min
-2147483648
-2147483648

Disclaimer:

It doesn't work for enums based on long.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Erik Karlsson
  • 570
  • 1
  • 6
  • 17
5

The example I would like to suggest "to get an 'int' value from an enum", is

public enum Sample
{
    Book = 1, 
    Pen = 2, 
    Pencil = 3
}

int answer = (int)Sample.Book;

Now the answer will be 1.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vivek
  • 137
  • 1
  • 5
  • 14
4

Try this one instead of convert enum to int:

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}
Nalan Madheswaran
  • 10,136
  • 1
  • 57
  • 42
4

Following is the 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;
}
Ashish Kamble
  • 2,555
  • 3
  • 21
  • 29
Kamran Shahid
  • 3,954
  • 5
  • 48
  • 93
0

In Visual Basic, it should be:

Public Enum Question
    Role = 2
    ProjectFunding = 3
    TotalEmployee = 4
    NumberOfServers = 5
    TopBusinessConcern = 6
End Enum

Private value As Integer = CInt(Question.Role)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
VPP
  • 731
  • 1
  • 9
  • 34
0

will give you the a list with all the integer values of the enum :

List enumValues = Enum.GetValues(typeof(EnumClass)).Cast().ToList();

IggyBar
  • 139
  • 1
  • 3
0
public enum ViewType
{
    List = 1,
    Table = 2,
};
            
// You can use the Enum type as a parameter, so any enumeration from any enumerator 
// cshtml
// using proyects.Helpers
// @if (Model.ViewType== (int)<variable>.List )
0

Nearly all of the current answers use Convert or cast to object before the target type, which results in boxing and unboxing operations. This causes heap allocations and may not be acceptable for hot paths.

Since the majority of these answers were written, System.Runtime.CompilerServices.Unsafe was introduced, enabling low-level manipulation of pointers.

In combination with generics, the Unsafe class allows us to change the underlying type of the System.Enum parameter safely, with zero allocations, and with performance that is nearly indistinguishable from an empty method duration:

public long GetEnumValue<T>(T enumInstance) where T : unmanaged, Enum
{
    var size = Unsafe.SizeOf<T>();
    
    if (size == Unsafe.SizeOf<byte>())
    {
        return Unsafe.As<T, byte>(ref enumInstance);
    }
    else if (size == Unsafe.SizeOf<short>())
    {
        return Unsafe.As<T, short>(ref enumInstance);
    }
    else if (size == Unsafe.SizeOf<int>())
    {
        return Unsafe.As<T, int>(ref enumInstance); 
    }
    else if (size == Unsafe.SizeOf<long>())
    {
        return Unsafe.As<T, long>(ref enumInstance);
    }
    
    return -1; // or throw if you prefer
}

Convert vs Unsafe benchmark


If it is preferable to always return an int, you can do so, although if the backing field of the enum exceeds int.MaxValue, it will overflow:

public int GetEnumValue<T>(T enumInstance) where T : unmanaged, Enum
{
    var size = Unsafe.SizeOf<T>();
    
    if (size == Unsafe.SizeOf<byte>())
    {
        return Unsafe.As<T, byte>(ref enumInstance);
    }
    else if (size == Unsafe.SizeOf<short>())
    {
        return Unsafe.As<T, short>(ref enumInstance);
    }
    else if (size == Unsafe.SizeOf<int>())
    {
        return Unsafe.As<T, int>(ref enumInstance); 
    }
    else if (size == Unsafe.SizeOf<long>())
    {
        return Unsafe.As<T, int>(ref enumInstance);
    }
    
    return -1; // or throw if you prefer
}

If the following were used:

public enum EnumLong : long
{
    First,
    Second,
    Third = (long)(int.MaxValue) + 1
}

var val = GetEnumValue(EnumLong.Third);

-2147483648 would be returned due to an overflow. It is extremely unlikely that developers would create enums with such large flag values, but is always a possibility.

David L
  • 32,885
  • 8
  • 62
  • 93
0
public int QuestionToInt(Question q)
{
    return (int)q;
}
SoulSystem
  • 51
  • 5
-2

I came up with this extension method that includes current language features. By using dynamic, I don't need to make this a generic method and specify the type which keeps the invocation simpler and consistent:

public static class EnumEx
{
    public static dynamic Value(this Enum e)
    {
        switch (e.GetTypeCode())
        {
            case TypeCode.Byte:
            {
                return (byte) (IConvertible) e;
            }

            case TypeCode.Int16:
            {
                return (short) (IConvertible) e;
            }

            case TypeCode.Int32:
            {
                return (int) (IConvertible) e;
            }

            case TypeCode.Int64:
            {
                return (long) (IConvertible) e;
            }

            case TypeCode.UInt16:
            {
                return (ushort) (IConvertible) e;
            }

            case TypeCode.UInt32:
            {
                return (uint) (IConvertible) e;
            }

            case TypeCode.UInt64:
            {
                return (ulong) (IConvertible) e;
            }

            case TypeCode.SByte:
            {
                return (sbyte) (IConvertible) e;
            }
        }

        return 0;
    }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeff
  • 646
  • 1
  • 7
  • 13
  • 1
    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 – Chad Grant Dec 27 '19 at 19:05
  • 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. – Jeff Feb 22 '20 at 20:19
  • 5
    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 – Chad Grant Feb 22 '20 at 20:44