75

In C, enums, internally equates to an integer. Therefore we can treat data types of enum as integer also.

How to achieve the same with C#?

2

9 Answers 9

113

Firstly, there could be two values that you're referring to:

Underlying Value

If you are asking about the underlying value, which could be any of these types: byte, sbyte, short, ushort, int, uint, long or ulong

Then you can simply cast it to it's underlying type. Assuming it's an int, you can do it like this:

int eValue = (int)enumValue;

However, also be aware of each items default value (first item is 0, second is 1 and so on) and the fact that each item could have been assigned a new value, which may not necessarily be in any order particular order! (Credit to @JohnStock for the poke to clarify).

This example assigns each a new value, and show the value returned:

public enum MyEnum
{
    MyValue1 = 34,
    MyValue2 = 27
}

(int)MyEnum.MyValue2 == 27; // True

Index Value

The above is generally the most commonly required value, and is what your question detail suggests you need, however each value also has an index value (which you refer to in the title). If you require this then please see other answers below for details.

8
  • 1
    The int value isn't necessarily the index as shown in user1027167's answer below. On second thought, I don't think it's clear if OP actually want the index or the int value... Commented Sep 5, 2019 at 14:41
  • This answer is wrong and makes huge assumptions about your enum in order for it to work.
    – John Stock
    Commented Oct 9, 2020 at 20:36
  • @JohnStock Sorry in what way is it wrong? Can you please elaborate? Bear in mind that it was written almost 10 years ago, and was written in response to someone who seemingly wanted a simple answer to a simple question, so yes assumptions were made and obviously it can, as always, be more complicated but it appears to have satisfied what they were seeking!
    – Iain Ward
    Commented Oct 10, 2020 at 22:51
  • OP is asking for an index. Your answer assumes that an enumeration has a consistent set of consecutive incrementing values like 1,2,3,4,5, which of course is very often not true with enumerations. It could be in a reverse order, not consecutive, seemingly random values or even not numeric at all. You should delete your answer because it only works for a very specific use case and will cause errors in other cases. If you read the other responses on this page, this error in your solution (and other people) has been pointed out numerous times. Nothing has changed in 10 years
    – John Stock
    Commented Oct 12, 2020 at 15:44
  • @JohnStock Ahh I see! Right OK, I understand what you're saying but to be honest it comes down to your interpretation if what he's asking. Although he states 'Index' in the title (and I'll admit I missed that) his actual question about enums equating to an integer suggests, and I believe in the majority of situations, refers to the underlying value of the enum, and not specifically the index value itself. I can't think of a situation where I've ever need the index value myself! (Is there one??) so yes, I made an assumption there and still believe it was the right decision as he accepted it.
    – Iain Ward
    Commented Oct 13, 2020 at 20:03
66

Another way to convert an Enum-Type to an int:

enum E
{
    A = 1,   /* index 0 */
    B = 2,   /* index 1 */
    C = 4,   /* index 2 */
    D = 4    /* index 3, duplicate use of 4 */
}

void Main()
{
    E e = E.C;
    int index = Array.IndexOf(Enum.GetValues(e.GetType()), e);
    // index is 2

    E f = (E)(Enum.GetValues(e.GetType())).GetValue(index);
    // f is  E.C
}

More complex but independent from the INT values assigned to the enum values.

3
  • 5
    This is a better answer than the accepted one (or the many other similar answers) since they all seem to assume that your enum values are assigned with sequential numeric values and often that is not the case. Commented Dec 6, 2017 at 0:46
  • Monster!!!! Nice answer. Worked perfectly in a method with generalization of Enum Type! Thanks
    – Peter R
    Commented Dec 2, 2019 at 12:11
  • 3
    Careful when using flags, the index is calculated by the numerically sorted value of the flag, and not the order in which they are defined. In above example, if instead you define A=1,C=4, B=2 then B still has an index of 1, even though it was defined after C. This can cause unexpected results when using composite flags. Again in above example if we add a new flag "AB = A | B' then its value will be 3, and the index of C will change from 2 in the above example to 3 as "AB' is slotted in between B and C in index order. Commented Sep 15, 2020 at 5:10
11

By default the underlying type of each element in the enum is integer.

enum Values
{
   A,
   B,
   C
}

You can also specify custom value for each item:

enum Values
{
   A = 10,
   B = 11,
   C = 12
}
int x = (int)Values.A; // x will be 10;

Note: By default, the first enumerator has the value 0.

1
  • what about second enumerator value? is it 1 ?
    – Fuat
    Commented Jan 30, 2019 at 13:44
7

You can directly cast it:

enum MyMonthEnum { January = 1, February, March, April, May, June, July, August, September, October, November, December };

public static string GetMyMonthName(int MonthIndex)
{
  MyMonthEnum MonthName = (MyMonthEnum)MonthIndex;
  return MonthName.ToString();
}

For Example:

string MySelectedMonthName=GetMyMonthName(8);
 //then MySelectedMonthName value will be August.
3

Use simple casting:

int value = (int) enum.item;

Refer to enum (C# Reference)

1
  • This isn't what the title asks for, this has, strictly speaking, nothing to do with the index of the enum entry.
    – Kresten
    Commented Jul 15, 2023 at 16:04
1

Use a cast:

public enum MyEnum : int    {
    A = 0,
    B = 1,
    AB = 2,
}


int val = (int)MyEnum.A;
1
using System;
public class EnumTest 
{
    enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};

    static void Main() 
    {

        int x = (int)Days.Sun;
        int y = (int)Days.Fri;
        Console.WriteLine("Sun = {0}", x);
        Console.WriteLine("Fri = {0}", y);
    }
}
0

One reason that the designers c# might have chosen to NOT have enums auto convert was to prevent accidentally mixing different enum types...

e.g. this is bad code followed by a good version
enum ParkingLevel { GroundLevel, FirstFloor};
enum ParkingFacing { North, East, South, West }
void Test()
{
    var parking = ParkingFacing.North; // NOT A LEVEL
    // WHOOPS at least warning in editor/compile on calls
    WhichLevel(parking); 

    // BAD  wrong type of index, no warning
    var info = ParkinglevelArray[ (int)parking ];
}


// however you can write this, looks complicated 
// but avoids using casts every time AND stops miss-use
void Test()
{
  ParkingLevelManager levels = new ParkingLevelManager();
  // assign info to each level
  var parking = ParkingFacing.North;

  // Next line wrong mixing type 
  // but great you get warning in editor or at compile time      
  var info=levels[parking];

  // and.... no cast needed for correct use
  var pl = ParkingLevel.GroundLevel;
  var infoCorrect=levels[pl];

}
class ParkingLevelInfo { /*...*/ }
class ParkingLevelManager
{
    List<ParkingLevelInfo> m_list;
    public ParkingLevelInfo this[ParkingLevel x] 
 { get{ return m_list[(int)x]; } }}
0

In answering this question I define 'value' as the value of the enum item, and index as is positional location in the Enum definition (which is sorted by value). The OP's question asks for 'index' and various answer have interpreted this as either 'index' or 'value' (by my definitions). Sometimes the index is equal to numerical value.

No answer has specifically addressed the case of finding the index (not value) where the Enum is an Enum flag.

Enum Flag
{
    none = 0       // not a flag, thus index =-1
    A = 1 << 0,   // index should be 0
    B = 1 << 1,   // index should be 1 
    C = 1 << 2,   // index should be 2 
    D = 1 << 3,   // index should be 3,
    AandB = A | B // index is composite, thus index = -1 indicating undefined
    All = -1      //index is composite, thus index = -1 indicating undefined
}

In the case of Flag Enums, the index is simply given by

var index = (int)(Math.Log2((int)flag)); //Shows the maths, but is inefficient

However, the above solution is (a) Inefficient as pointed out by @phuclv (Math.Log2() is floating point and costly) and (b) Does not address the Flag.none case, nor any composite flags - flags that are composed of other flags (eg the 'AandB' flag as in my example).

DotNetCore If using dot net core we can address both a) and b) above as follows:

int setbits = BitOperations.PopCount((uint)flag); //get number of set bits
if (setbits != 1) //Finds ECalFlags.none, and all composite flags
    return -1;   //undefined index
int index = BitOperations.TrailingZeroCount((uint)flag); //Efficient bit operation

Not DotNetCore The BitOperations only work in dot net core. See @phuclv answer here for some efficient suggestions https://stackoverflow.com/a/63582586/6630192

  • @user1027167 answer will not work if composite flags are used, as per my comment on his answer
  • Thankyou to @phuclv for suggestions on improving efficiency
5
  • Math.Log2 is very slow, BitOperations.TrailingZeroCount will be much faster. And you don't need Convert.ToInt32 to get an int, a simple cast is enough How to get numeric position of an enum in its definition list?
    – phuclv
    Commented Sep 15, 2020 at 6:33
  • this assumes a particular definition of "index" (although note that in the actual question, when OP says "index" they actually mean "value"); a valid argument could be made that the "index" should refer to enum values that are defined, therefore since None=0 is defined first, it would have index 0 - but that then gets into further complications because the order of reflection APIs is not itself defined! My point: there are a lot of definitional things in this answer that are implicitly assumed to be axiomatic, but which are more subtle than that Commented Sep 15, 2020 at 9:08
  • @Marc Gravell agree there is ambiguity between 'index' and 'value'. Therefore we define 'value' as the value of the enum item, and index as is positional location in the enum definition (which is sorted by value). There are many other questions that look at the value, but I came here specifically looking for index-the positional location.. A number of other answers have implicitly defined index similarly, and as separate to value (see @user1027167). Regarding None=0, in a Flags Enum it could not be considered an index, as it can not be used as a Flag..It is a good point you make though. Commented Sep 15, 2020 at 10:03
  • "and index as is positional location in the enum definition (which is sorted by value)" - those are conflicting statements; the enum definition does not have to be sorted by value (and the values do not need to be distinct), and it is not possible to deduce the definition order at runtime, because the reflection API explicitly does not define/guarantee order Commented Sep 15, 2020 at 10:11
  • @MarcGravell. Hi Marc, focusing only on Enum Flags, while the values may not need to be distinct, we always define them as distinct as that is necessary for the the flags to be distinct. Given that, the index of or distinct flags are sorted by the numerical value of the flag. For example let flags be A=1 <<0, B=1<<1, C= 1<<2 as defined in that numerical order. We expect the indexes to be A=0, B=1. C=2 Now if we add a composite flag AandB = A|B, then we should expect the indexes to be the same., but by value order they become A=0,B=1, C=3, as A|B slips in between them. My answer avoids this Commented Sep 15, 2020 at 10:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.