'How to get enum order?
If I have enum:
public enum ImportState : byte
{
None = 0,
ImportedWithChanges = 44,
AwaitingApproval = 45,
Removing = 66,
Revalidating = 99,
};
How to get enum order? For example:
GetOrder(ImportState.None)
Should return 1(first in order)
GetOrder(ImportState.AwaitingApproval )
Should return 3 (third in order)
Solution 1:[1]
As other noticed, Enum.GetValues() returns the values of an enum sorted by value. Perhaps this isn't what you wanted... So, using a little reflection:
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);
}
}
Example of use:
public enum Values
{
Foo = 10,
Bar = 1
}
int ix = EnumOrder<Values>.IndexOf(Values.Bar); // 1
Note that the C# specifications aren't clear if the "source code" ordering of an enum is maintained in the compiled program... At this time the C# compiler seems to maintain it, but there is no guarantee in the future...
The only two references I've found are:
Forward declarations are never needed in C# because, with very few exceptions, declaration order is insignificant
and
Declaration order for enum member declarations (§14.3) is significant when constant-expression values are omitted.
So as written, for the example I gave, the ordering is undefined and depends on the C# compiler!
Solution 2:[2]
Enumerating the enum values, casting to an IEnumerable, converting to a List. This it is a simple matter of using IndexOf().
Note that for this to work, the enum must be declared in increasing order.
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 . . .
Solution 3:[3]
Sth. like this?
int i = 0;
foreach (ImportState state in Enum.GetValues(typeof(ImportState)))
{
i++;
if (state == myState) return i;
}
However there is no real use for this, as enums do not provide an indexed enumeration in themselfes. They represent a value which is more what you´re probably after.
Solution 4:[4]
You can use this LINQ query:
int position = Enum.GetValues(typeof(ImportState)).Cast<ImportState>()
//.OrderBy(impState => (int)impState)
.TakeWhile(impState => impState != ImportState.None)
.Count() + 1;
It orders by the int-value of the enum-value, then it takes all until the searched value and counts them. I have omitted the OrderBy since Enum.GetValues automatically returns the order according to their int-value.
MSDN:
The elements of the array are sorted by the binary values of the enumeration constants
Solution 5:[5]
Instead of using the order, you would be better to make better use of the flags. Consider the following
public enum ImportState : byte
{
None = 0,
ImportedWithChanges = 2,
AwaitingApproval = 4,
Removing = 6,
Revalidating = 8,
};
(double)state / Enum.GetValues(typeof(ImportState)).Cast<byte>().Max()
Enums don't really have any sense of ordering, using the above probably still isn't perfect but it doesn't involve a made up order.
Solution 6:[6]
What about this Solution?
var result = from r in Enum.GetValues<ImportState>()
let expression =
r == ImportState.Revalidating
? 0
: r == ImportState.AwaitingApproval
? 1
: r == ImportState.Removing
? 2
: r == ImportState.ImportedWithChanges
? 3
: 4
orderby expression ascending
select r.ToString();
Console.WriteLine(string.Join(", ", result));
Output: Revalidating, AwaitingApproval, Removing, ImportedWithChanges, None
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | xanatos |
| Solution 2 | Micke |
| Solution 3 | |
| Solution 4 | |
| Solution 5 | Sayse |
| Solution 6 | SergeyVoskoboynikov |
