簡體   English   中英

如何獲取 C# 中的枚舉索引值

[英]How to get the Enum Index value in C#

在 C 中, enums內部等同於 integer。 因此,我們也可以將enum的數據類型視為 integer。

如何實現與 C# 相同?

首先,您可能指的是兩個值:

基礎價值

如果您詢問基礎值,它可能是以下任何類型:byte、sbyte、short、ushort、int、uint、long 或 ulong

然后你可以簡單地將它轉換為它的底層類型。 假設它是一個int ,你可以這樣做:

int eValue = (int)enumValue;

但是,還要注意每個項目的默認值(第一個項目是 0,第二個項目是 1,依此類推)以及每個項目可能已被分配一個新值的事實,這可能不一定是任何特定順序的順序。 (感謝@JohnStock 澄清)。

此示例為每個分配一個新值,並顯示返回的值:

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

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

指數值

以上通常是最常用的值,並且是您的問題詳細信息表明您需要的值,但是每個值也有一個索引值(您在標題中引用)。 如果您需要,請參閱下面的其他答案以獲取詳細信息。

將 Enum-Type 轉換為 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
}

更復雜但獨立於分配給枚舉值的 INT 值。

默認情況下,枚舉中每個元素的基礎類型是 integer。

enum Values
{
   A,
   B,
   C
}

您還可以為每個項目指定自定義值:

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

注意:默認情況下,第一個枚舉數的值為 0。

您可以直接投射它:

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

例如:

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

使用簡單的鑄造:

int value = (int) enum.item;

請參閱枚舉(C# 參考)

使用演員表:

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


int val = (int)MyEnum.A;
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);
    }
}

設計師 c# 可能選擇不使用枚舉自動轉換的原因之一是為了防止意外混合不同的枚舉類型......

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

在回答這個問題時,我將“值”定義為枚舉項的值,並將索引定義為枚舉定義中的位置(按值排序)。 OP的問題要求“索引”,各種答案將其解釋為“索引”或“值”(根據我的定義)。 有時索引等於數值。

沒有答案專門解決了查找 Enum 是 Enum 標志的索引(不是值)的情況。

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
}

在標志枚舉的情況下,索引簡單地由下式給出

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

但是,上述解決方案是(a)@phuclv 指出的效率低下(Math.Log2() 是浮點且成本高)和(b)沒有解決 Flag.none 情況,也沒有任何復合標志 - 組成的標志其他標志(例如我的示例中的“AandB”標志)。

DotNetCore如果使用 dot net core,我們可以同時解決上面的 a) 和 b),如下所示:

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

不是 DotNetCore BitOperations 僅適用於 dot net core。 請參閱@phuclv 的答案以獲得一些有效的建議https://stackoverflow.com/a/63582586/6630192

  • 根據我對他的回答的評論,如果使用復合標志,@user1027167 答案將不起作用
  • 感謝@phuclv 提供關於提高效率的建議

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM