Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OrderBy on Enum.GetValues()

Tags:

c#

enums

linq

I'm populating a DropDownList in MVC 4 from an enum and I want to order the enum values from largest to smallest. However, there doesn't seem to be a direct way of approaching this. Currently, I'm using this code to add to a dictionary with the key being the ID and the value being the display text:

var priorities = Enum.GetValues(typeof(Models.Priority)).OfType<Models.Priority>().ToList();

for (int i = priorities.Count - 1; i >= 0; i--)
{
    Models.Priority priority = priorities[i];
    prioritiesDictionary.Add((int)priority, "Priority " + ((int)priority).ToString());
}

I don't believe that putting enum values into a list and looping backwards is the most efficient method. There are only four values in the enum, but is there a better way to perform an OrderBy operation on what is returned from Enum.GetValues? I know it might be minimal performance impact doing it the way I am, but I want to know for larger enums.

like image 812
Cameron Tinker Avatar asked Oct 25 '13 20:10

Cameron Tinker


People also ask

What does enum GetValues return?

The GetValues method returns an array that contains a value for each member of the enumType enumeration.

How to get Values from an enum?

Get the value of an Enum To get the value of enum we can simply typecast it to its type. In the first example, the default type is int so we have to typecast it to int. Also, we can get the string value of that enum by using the ToString() method as below.

What is enum class in C#?

Enumeration (or enum) is a value data type in C#. It is mainly used to assign the names or string values to integral constants, that make a program easy to read and maintain.

What are enum types?

An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.


2 Answers

Sounds like you just want:

var priorities = ((Models.Priority[]) Enum.GetValues(typeof(Models.Priority)))
                                          .OrderByDescending(x => x);

Or to avoid quite as many brackets:

var priorities = (Models.Priority[]) Enum.GetValues(typeof(Models.Priority));
var ordered = priorities.OrderByDescending(x => x);

It's not clear how your current code is helping you, by giving you a dictionary - but the above will definitely give you a sequence of enum values, ordered from highest to lowest. You don't need to cast to int, because enum values of the same type are already comparable to each other.

If you need a list, just call ToList() after the OrderByDescending call.

like image 120
Jon Skeet Avatar answered Sep 19 '22 13:09

Jon Skeet


What about this:

Enum.GetValues(typeof(Models.Priority))
    .Cast<Models.Priority>()
    .OrderByDescending(x => (int) x)
    .ToList();

You shouldn't use OfType<T>() in this style of logic because that silently throws away non-matching items. In this case a non-matching item would indicate a serious error or misuse.

If the expectation is that all items will already be a certain type, then we use Cast<T>().

OfType<T> is a filter operation, it is intended for use in scenarios where we know some items can not be cast to the expected type. OfType<T> is therefore useful in lists that might contain null valued items.

OfType<T> is commonly used in expressions that operate over untyped or object enumerations like Type Attribute or when the enumeration is a base type and you only want objects of a specific implementation, or that implement a specific interface.

like image 42
usr Avatar answered Sep 18 '22 13:09

usr