繁体   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