How to get the Enum Index value in C#

C#CEnumsInteger

C# Problem Overview


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

C# Solutions


Solution 1 - C#

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.

Solution 2 - C#

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.

Solution 3 - C#

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.

Solution 4 - C#

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.

Solution 5 - C#

Use simple casting:

int value = (int) enum.item;

Refer to enum (C# Reference)

Solution 6 - C#

Use a cast:

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


int val = (int)MyEnum.A;

Solution 7 - C#

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

Solution 8 - C#

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]; } }}

Solution 9 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShamim Hafiz - MSFTView Question on Stackoverflow
Solution 1 - C#Iain WardView Answer on Stackoverflow
Solution 2 - C#user1027167View Answer on Stackoverflow
Solution 3 - C#HomamView Answer on Stackoverflow
Solution 4 - C#Durgesh PandeyView Answer on Stackoverflow
Solution 5 - C#Akram ShahdaView Answer on Stackoverflow
Solution 6 - C#thumbmunkeysView Answer on Stackoverflow
Solution 7 - C#AravindView Answer on Stackoverflow
Solution 8 - C#PJJView Answer on Stackoverflow
Solution 9 - C#JimbobTheSailorView Answer on Stackoverflow