我需要在其定义中获取枚举的数字位置。 请考虑以下枚举 - 它用于位字段,但用于状态名称 如果他们拥有我评论过的右边的值,那将会非常有用。
[Flags]
public enum StatusFlags
{
None = 0, // 0 -- these commented indexes are the numbers I also would like
Untested = 1, // 1 to associate with the enum names.
Passed_Programming = 2, // 2
Failed_Programming = 4, // 3
// ... many more
}
我已经创建了一个静态方法,如下所示。
public static int GetStatusID(this StatusFlags flag)
{
int i = 0;
foreach (StatusFlags val in Enum.GetValues(typeof(StatusFlags)))
{
if (flag == val) break;
i++;
}
return i;
}
它的用法如下:
StatusFlags f = StatusFlags.Failed_Programming;
// I want the position i.e value of 3 not the value the enum is associated with i.e 4
int Index = f.GetStatusID();
有更好的方法吗?
答案 0 :(得分:3)
你可以这样做:
public static int GetStatusID(this StatusFlags flag)
{
return
Enum
.GetValues(typeof(StatusFlags))
.Cast<StatusFlags>()
.Select((f, n) => new { f, n })
.Where(fn => fn.f == flag)
.Select(fn => fn.n)
.DefaultIfEmpty(0)
.First();
}
答案 1 :(得分:2)
如何在枚举上使用属性?像这样:
[Flags]
public enum StatusFlags
{
[Index=0]
None = 0,
[Index=1]
Untested = 1,
[Index=2]
Passed_Programming = 2,
[Index=3]
Failed_Programming = 4,
// ... many more
}
然后你可以像这样枚举你的枚举的索引值:
var type = typeof(StatusFlags);
var statusFlag = type.GetMember(StatusFlags.Untested.ToString());
var attributes = statusFlag [0].GetCustomAttributes(typeof(IndexAttribute),false);
var index = int.Parse(((IndexAttribute)attributes[0]).Index); //if you need an int value
答案 2 :(得分:1)
这里删除的答案提示了类似
的内容public static int GetStatusID(this StatusFlags flag)
{
return Array.IndexOf(Enum.GetValues(typeof(StatusFlags)), flag);
}
并且只是缺少语法点,即IndexOf是Array类中的静态函数,而不是扩展方法。我喜欢它,但为了简洁起见。
答案 3 :(得分:1)
如何使用数学?他说,上升的力量是2
int GetStatusID(this StatusFlags flag)
{
if (((int)flag) == 0) return 0;
return (Math.Log((double)flag) / Math.Log(2D)) + 1;
}
答案 4 :(得分:0)
如果每个标志只设置了1位,则索引仅为Math.Log2((int)flag) + 1
。但是Math.Log2
是浮点运算,并且速度很慢,因此请不要使用它
如果您使用的是.NET Core,则有BitOperations.TrailingZeroCount
可以直接映射到x86中的TZCNT / BSF指令或相应体系结构中的类似指令,因此效率更高,结果是这样
public static int GetStatusID(this StatusFlags flag)
{
if ((int)flag == 0)
return 0;
return BitOperations.TrailingZeroCount((int)flag) + 1;
}
如果您使用的是较旧的.NET框架,那么请计算这些问题中的快速计算整数log2的方法