如何获得枚举顺序?

时间:2015-06-15 12:32:36

标签: c#

如果我有枚举:

public enum ImportState : byte
{
     None = 0,
     ImportedWithChanges = 44,
     AwaitingApproval = 45,
     Removing = 66,
     Revalidating = 99,
};

如何获得枚举顺序? 例如:

GetOrder(ImportState.None)

应该返回1(按顺序排列)

GetOrder(ImportState.AwaitingApproval )

应该返回3(按顺序排列第三)

6 个答案:

答案 0 :(得分:2)

这是缺少的方法GetOrder

public static int GetOrder(ImportState State)
{
    return Enum.GetValues(typeof(ImportState)).Cast<ImportState>().Select((x, i) => new { item = x, index = i }).Single(x => x.item == State).index;
}

答案 1 :(得分:2)

正如其他人注意到的那样,Enum.GetValues()返回按值排序的枚举值。也许这不是你想要的......所以,使用一点反思:

public class EnumOrder<TEnum> where TEnum : struct
{
    private static readonly TEnum[] Values;

    static EnumOrder()
    {
        var fields = typeof(Values).GetFields(BindingFlags.Static | BindingFlags.Public);
        Values = Array.ConvertAll(fields, x => (TEnum)x.GetValue(null));
    }

    public static int IndexOf(TEnum value)
    {
        return Array.IndexOf(Values, value);
    }
}

使用示例:

public enum Values
{
    Foo = 10,
    Bar = 1
}

int ix = EnumOrder<Values>.IndexOf(Values.Bar); // 1

请注意,如果在编译的程序中维护enum的“源代码”顺序,则不清楚C#规范......此时C#编译器似乎维护它,但是没有保证将来...

我发现的唯一两个参考文献是:

  

C#中永远不需要前向声明,因为除了极少数例外,声明顺序无关紧要

  

当省略常量表达式值时,枚举成员声明(第14.3节)的声明顺序很重要。

正如所写的那样,对于我给出的例子,排序是未定义的,取决于C#编译器!

答案 2 :(得分:1)

枚举枚举值,转换为IEnumerable,转换为List。这是一个使用IndexOf()的简单问题。

请注意,要使其正常工作,必须按递增顺序声明枚举

namespace ConsoleApplication1
{
    using System;
    using System.Linq;

    class Program
    {
        public enum ImportState : byte
        {
            None = 0,
            ImportedWithChanges = 44,
            AwaitingApproval = 45,
            Removing = 66,
            Revalidating = 99,
        }

        static void Main(string[] args)
        {
            Console.WriteLine(GetOrder(ImportState.None));
            Console.WriteLine(GetOrder(ImportState.AwaitingApproval));
        }

        public static int GetOrder(ImportState state)
        {
            var enumValues = Enum.GetValues(typeof(ImportState)).Cast<ImportState>().ToList();

            return enumValues.IndexOf(state) + 1; // +1 as the IndexOf() is zero-based
        }
    }
}
1
3
Press any key to continue . . .

答案 3 :(得分:0)

STH。像这样?

int i = 0;
foreach (ImportState state in Enum.GetValues(typeof(ImportState)))
{
    i++;
    if (state == myState) return i;
}

然而,这并没有真正的用途,因为枚举不会在自己中提供索引枚举。它们代表的是一个你可能追求的价值。

答案 4 :(得分:0)

您可以使用此LINQ查询:

int position = Enum.GetValues(typeof(ImportState)).Cast<ImportState>()
    //.OrderBy(impState => (int)impState)
    .TakeWhile(impState => impState != ImportState.None)
    .Count() + 1;

按枚举值的int值排序,然后直到搜索到的值并计算它们。我省略了OrderBy,因为Enum.GetValues会根据它们的int值自动返回订单。

MSDN

  

数组的元素按照二进制值排序   枚举常量

答案 5 :(得分:0)

不是使用订单,而是更好地利用这些标志。请考虑以下

public enum ImportState : byte
{
     None = 0,
     ImportedWithChanges = 2,
     AwaitingApproval = 4,       
     Removing = 6,
     Revalidating = 8,
};
(double)state / Enum.GetValues(typeof(ImportState)).Cast<byte>().Max()

Example

Enums实际上并没有任何排序感,使用上面的内容可能仍然不完美,但它不涉及订单。