OrderBy on Enum.GetValues()



我正在从enum填充 MVC 4 中的DropDownList,我想从大到小对枚举值进行排序。但是,似乎没有直接的方法可以解决这个问题。目前,我正在使用此代码添加到字典中,键是 ID,值是显示文本:

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());
}

我不认为将枚举值放入列表中并向后循环是最有效的方法。枚举中只有四个值,但是有没有更好的方法对从Enum.GetValues返回的内容执行OrderBy操作?我知道以我的方式这样做对性能的影响可能很小,但我想知道更大的枚举。

听起来你只是想要:

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

或者为了避免太多的括号:

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

目前还不清楚你当前的代码是如何帮助你的,通过给你一个字典 - 但上面肯定会给你一个枚举值序列,从最高到最低排序。你不需要强制转换为int,因为相同类型的枚举值已经彼此可比。

如果您需要列表,只需在OrderByDescending通话后致电ToList()即可。

这个呢:

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

您不应该在这种逻辑风格中使用OfType<T>(),因为这会静默地丢弃不匹配的项目。在这种情况下,不匹配的项目将表示存在严重错误或误用。

如果期望所有项目都已经是某种类型,那么我们使用 Cast<T>() .

OfType<T>是一个筛选器操作,但它适用于我们知道某些项无法强制转换为预期类型的方案。 因此,OfType<T>在可能包含null值项的列表中很有用。

OfType<T>通常用于对非类型化或object枚举(如 Type Attribute)进行操作的表达式中,或者当枚举是基类型并且您只需要特定实现的对象或实现特定接口的对象时。

基于上述,我创建了一个可重用的函数...

    public static IOrderedEnumerable<TEnum> Sort<TEnum>()
    {
        return ((TEnum[]) Enum.GetValues(typeof (TEnum))).OrderBy(x => x.ToString());
    }
我想

声明一个可以这样使用的枚举助手:

Enum<MyEnum>.ValuesAscending

这是帮手

using System;
using System.Collections.Generic;
using System.Linq;
...
  public static class Enum<T>
    where T : struct, Enum
  {
    public static readonly IReadOnlyList<T> ValuesAscending = Enum.GetValues( typeof( T ) ).Cast<T>().Distinct().OrderBy( v => v ).ToArray();
    public static readonly IReadOnlyList<T> ValuesDescending = Enum.GetValues( typeof( T ) ).Cast<T>().Distinct().OrderByDescending( v => v ).ToArray();
    public static readonly IReadOnlyList<string> NamesAscending = Enum.GetNames( typeof( T ) ).OrderBy( s => s ).ToArray();
    public static readonly IReadOnlyList<string> NamesDescending = Enum.GetNames( typeof( T ) ).OrderByDescending( s => s ).ToArray();
  };

注意:ValuesAscendingValuesDescending 都消除了重复项,并且仍然可以使用 int 以外的枚举类型。这些列表也使用静态类的静态成员的魔力进行缓存,尽管如果需要,我不能保证线程安全。如果同时使用这四个,您还可以在降序上使用.Reverse().ToArray()以节省一些时间。

如果你想要更多的帮手,我这里有一个更广泛的版本:https://github.com/cgbeutler/CSharpEnumExt

最新更新