在回答这个问题时,我将“值”定义为枚举项的值,并将索引定义为枚举定义中的位置(按值排序)。 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
}
在 Flag Enums 的情况下,索引简单地由下式给出
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 仅适用于点网核心。请参阅此处的@phuclv 答案以获取一些有效的建议https://stackoverflow.com/a/63582586/6630192
- @user1027167 根据我对他的回答的评论,如果使用复合标志,则答案将不起作用
- 感谢@phuclv 提供有关提高效率的建议