我有一个这样的枚举:
enum MyEnum{
[Order(1)]
ElementA = 1,
[Order(0)]
ElementB = 2,
[Order(2)]
ElementC = 3
}
我想列出按我编写的自定义顺序属性排序的元素,以便我得到一个已排序的项目列表。
我正在获取描述属性,但仅适用于这样的一个元素:
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
它可能是相同的但需要处理所有枚举并返回列表或其他已排序的枚举。
答案 0 :(得分:9)
假设OrderAttribute
类如下:
public class OrderAttribute : Attribute
{
public readonly int Order;
public OrderAttribute(int order)
{
Order = order;
}
}
获取枚举值的辅助方法:
public static T[] SortEnum<T>()
{
Type myEnumType = typeof(T);
var enumValues = Enum.GetValues(myEnumType).Cast<T>().ToArray();
var enumNames = Enum.GetNames(myEnumType);
int[] enumPositions = Array.ConvertAll(enumNames, n =>
{
OrderAttribute orderAttr = (OrderAttribute)myEnumType.GetField(n)
.GetCustomAttributes(typeof(OrderAttribute), false)[0];
return orderAttr.Order;
});
Array.Sort(enumPositions, enumValues);
return enumValues;
}
答案 1 :(得分:5)
如果我清楚地了解您的问题,可以采用以下解决方案:
public static class EnumExtenstions
{
public static IEnumerable<TEnum> EnumGetOrderedValues<TEnum>(this Type enumType)
{
var fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);
var orderedValues = new List<Tuple<int, TEnum>>();
foreach (var field in fields)
{
var orderAtt = field.GetCustomAttributes(typeof(EnumOrderAttribute), false).SingleOrDefault() as EnumOrderAttribute;
if (orderAtt != null)
{
orderedValues.Add(new Tuple<int, TEnum>(orderAtt.Order, (TEnum)field.GetValue(null)));
}
}
return orderedValues.OrderBy(x=>x.Item1).Select(x=>x.Item2).ToList();
}
}
用法:
var result = typeof(enumType).EnumGetOrderedValues<enumType>();
答案 2 :(得分:1)
鉴于
Value
然后你可以:
Value
所以排序就像:
[AttributeUsage(AttributeTargets.Field)]
public class OrderAttribute : Attribute
{
public readonly int Order;
public OrderAttribute(int order)
{
Order = order;
}
}
public static class OrderHelper
{
public static int GetOrder<TEnum>(TEnum value) where TEnum : struct
{
int order;
if (!OrderHelperImpl<TEnum>.Values.TryGetValue(value, out order))
{
order = int.MaxValue;
}
return order;
}
private static class OrderHelperImpl<TEnum>
{
public static readonly Dictionary<TEnum, int> Values;
static OrderHelperImpl()
{
var values = new Dictionary<TEnum, int>();
var fields = typeof(TEnum).GetFields(BindingFlags.Static | BindingFlags.Public);
int unordered = int.MaxValue - 1;
for (int i = fields.Length - 1; i >= 0; i--)
{
FieldInfo field = fields[i];
var order = (OrderAttribute)field.GetCustomAttributes(typeof(OrderAttribute), false).FirstOrDefault();
int order2;
if (order != null)
{
order2 = order.Order;
}
else
{
order2 = unordered;
unordered--;
}
values[(TEnum)field.GetValue(null)] = order2;
}
Values = values;
}
}
}
或LINQ:
int o1 = OrderHelper.GetOrder(MyEnum.ElementA);
int o2 = OrderHelper.GetOrder(MyEnum.ElementB);
int o3 = OrderHelper.GetOrder(MyEnum.ElementC);
var myenums = new[] { MyEnum.ElementA, MyEnum.ElementB, MyEnum.ElementC };
Array.Sort(myenums, (p, q) => OrderHelper.GetOrder(p).CompareTo(OrderHelper.GetOrder(q)));
&#34;缓存&#34; var myenums = new[] { MyEnum.ElementA, MyEnum.ElementB, MyEnum.ElementC };
var sorted = myenums.OrderBy(x => OrderHelper.GetOrder(x));
内的排序。通过知道在枚举中值为OrderHelper
字段(您可以很容易地看到它here)来提取枚举的值。
没有OrderHelperImpl<TEnum>
的值按照public static
中的相同顺序排序,方法是使用Order
下方enum
的最大可能值{} p>
答案 3 :(得分:0)
public class OrderAttribute : Attribute
{
public int priority;
public OrderAttribute(int priority)
{
this.priority = priority;
}
}
public enum Test
{
[Order(1)] value1 = 1,
[Order(2)] value2 = 2,
[Order(0)] value3 = 3
}
private static void Main(string[] args)
{
Dictionary<string, int> priorityTable = new Dictionary<string, int>();
var values = Enum.GetValues(typeof (Test)).Cast<Test>();
MemberInfo[] members = typeof (Test).GetMembers();
foreach (MemberInfo member in members)
{
object[] attrs = member.GetCustomAttributes(typeof(OrderAttribute), false);
foreach (object attr in attrs)
{
OrderAttribute orderAttr = attr as OrderAttribute;
if (orderAttr != null)
{
string propName = member.Name;
int priority = orderAttr.priority;
priorityTable.Add(propName, priority);
}
}
}
values = values.OrderBy(n => priorityTable[n.ToString("G")]);
foreach (var value in values)
{
Console.WriteLine(value);
}
Console.ReadLine();
}
这将输出:
值3
值1
值2