在枚举扩展帮助中返回枚举列表而不是字符串
问题描述:
如何将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();
答
枚举类型变量的扩展方法是没有意义的,因为您不需要该变量的值 - 您只需要枚举类型。所以,我会去与静态辅助类:
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);
}
}
注:枚举类型非静态value
场,其实际持有的枚举值。所以如果你想列举枚举成员,你只需要使用静态字段。
使用
var values = Enum<Fruits>.GetOrderedValues();
对于样品枚举
public enum Fruits
{
Banana,
[EnumOrder(2)]
Apple,
[EnumOrder(1)]
Lemon
}
输出将被
[ Lemon, Apple, Banana ]
成员没有EnumOrder
属性将在最后一次去,但如果你愿意,你可以改变这种行为使用其他一些默认订单而不是Int32.MaxValue
。
+0
这是疯了:) –
只是想知道 - 为什么你会有没有按字母顺序或按价值排序的枚举成员的顺序? –
也许是因为它们存储在数据库中,并且添加新的枚举可能需要在显示时按特定顺序放置,但与存储的值无关。 –
把'EnumOrderAttribute'放在'Enum'值上并且在迭代Enum.GetValues()'时检查它是否更有意义? – DiskJunky