Reputation: 4009
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)
Upvotes: 1
Views: 5621
Reputation: 51
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
Upvotes: 0
Reputation: 43330
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.
Upvotes: 0
Reputation: 111940
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!
Upvotes: 3
Reputation: 460340
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
Upvotes: 0
Reputation: 2309
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 . . .
Upvotes: 1
Reputation: 37113
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.
Upvotes: 0
Reputation: 46005
here is the missing method 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;
}
Upvotes: 2