C# 在枚举扩展帮助程序中返回枚举列表而不是字符串

C# 在枚举扩展帮助程序中返回枚举列表而不是字符串,c#,.net,enums,extension-methods,C#,.net,Enums,Extension Methods,如何转换GetWithOrder方法以正确的顺序返回实际枚举?它适用于枚举的字符串,但我需要实际的枚举值,当然还需要是泛型的 [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] public class EnumOrderAttribute : Attribute { public int Order { get; set; } } public static class EnumExtenstions {

如何转换
GetWithOrder
方法以正确的顺序返回实际枚举?它适用于枚举的字符串,但我需要实际的枚举值,当然还需要是泛型的

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class EnumOrderAttribute : Attribute
{
    public int Order { get; set; }
}


public static class EnumExtenstions
{
    public static IEnumerable<string> GetWithOrder(this Enum enumVal)
    {
        return enumVal.GetType().GetWithOrder();
    }

    public static IEnumerable<string> GetWithOrder(this Type type)
    {
        if (!type.IsEnum)
        {
            throw new ArgumentException("Type must be an enum");
        }
        // caching for result could be useful
        return type.GetFields()
                               .Where(field => field.IsStatic)
                               .Select(field => new
                                            {
                                                field,
                                                attribute = field.GetCustomAttribute<EnumOrderAttribute>()
                                            })
                                .Select(fieldInfo => new
                                             {
                                                 name = fieldInfo.field.Name,
                                                 order = fieldInfo.attribute != null ? fieldInfo.attribute.Order : 0
                                             })
                               .OrderBy(field => field.order)
                               .Select(field => field.name);
    }
}

public enum TestEnum
{
    [EnumOrder(Order=2)]
    Second = 1,

    [EnumOrder(Order=1)]
    First = 4,

    [EnumOrder(Order=3)]
    Third = 0
}

var names = typeof(TestEnum).GetWithOrder();
var names = TestEnum.First.GetWithOrder();
[AttributeUsage(AttributeTargets.Field,AllowMultiple=false)]
公共类EnumOrderAttribute:属性
{
公共整数顺序{get;set;}
}
公共静态类枚举扩展
{
公共静态IEnumerable GetWithOrder(此枚举枚举值)
{
返回enumVal.GetType().GetWithOrder();
}
公共静态IEnumerable GetWithOrder(此类型)
{
如果(!type.IsEnum)
{
抛出新ArgumentException(“类型必须是枚举”);
}
//缓存结果可能很有用
返回类型。GetFields()
.Where(field=>field.IsStatic)
.选择(字段=>新建)
{
领域
attribute=field.GetCustomAttribute()
})
.选择(字段信息=>新建
{
name=fieldInfo.field.name,
order=fieldInfo.attribute!=null?fieldInfo.attribute.order:0
})
.OrderBy(field=>field.order)
.Select(field=>field.name);
}
}
公共枚举测试数
{
[EnumOrder(Order=2)]
秒=1,
[EnumOrder(Order=1)]
第一个=4,
[顺序(顺序=3)]
第三=0
}
var name=typeof(TestEnum).GetWithOrder();
var name=TestEnum.First.GetWithOrder();

枚举类型变量的扩展方法没有意义,因为您不需要该变量的值-只需要枚举类型。因此,我将使用静态帮助器类:

public static class Enum<T>
{
    public static IEnumerable<T> GetOrderedValues()
    {
        var type = typeof(T);
        if (!type.IsEnum)
            throw new InvalidOperationException();

        return from f in type.GetFields(BindingFlags.Static | BindingFlags.Public)
               orderby f.GetCustomAttribute<EnumOrderAttribute>()?.Order ?? Int32.MaxValue
               select (T)f.GetValue(obj: null);
    }
}
用于样本枚举

public enum Fruits
{
    Banana,
    [EnumOrder(2)]
    Apple,
    [EnumOrder(1)]
    Lemon
}
输出将是

[ Lemon, Apple, Banana ]

没有
EnumOrder
属性的成员将排在最后,但如果您使用其他默认顺序而不是
Int32.MaxValue

则可以更改该行为。只是想知道-为什么枚举成员的顺序不是按字母或值排序的?可能是因为它们存储在数据库中,添加新的枚举可能需要在显示时按一定的顺序排列,但与存储的值无关。将
EnumOrderAttribute
放在
Enum
值上,并在迭代
Enum.GetValues()
时简单地检查它是否更有意义
[ Lemon, Apple, Banana ]