2010-02-09 6 views
5

Я работаю в C# .NEt 2.0. У меня есть класс, скажем X со многими свойствами. У каждого свойства есть пользовательский атрибут, межсетевой экран, который я планировал использовать, чтобы указать его порядок в конечном массиве.Как отсортировать общий список на основе пользовательского атрибута?

Использование отражения Я прочитал все свойства и сгруппировал значения и поместил их в общий список свойств. Это работает, и я могу захватить ценности. Но план был списком SORT, основанным на пользовательском атрибуте, размещенном на каждом свойстве, и, наконец, зачитал значения свойств, уже упорядоченных, в строку.

ответ

11

Допустим, вы имели следующее определение атрибута

public class SortAttribute : Attribute { 
    public int Order { get; set; } 
    public SortAttribute(int order) { Order = order; } 
} 

Вы можете использовать следующий код, чтобы вытащить свойства на тип в отсортированном порядке. Предполагая, что, конечно, все они имеют этот атрибут

public IEnumerable<object> GetPropertiesSorted(object obj) { 
    Type type = obj.GetType(); 
    List<KeyValuePair<object,int>> list = new List<KeyValuePair<object,int>>(); 
    foreach (PropertyInfo info in type.GetProperties()) { 
    object value = info.GetValue(obj,null); 
    SortAttribute sort = (SortAttribute)Attribute.GetCustomAttribute(x, typeof(SortAttribute), false); 
    list.Add(new KeyValuePair<object,int>(value,sort.Order)); 
    } 
    list.Sort(delegate (KeyValuePair<object,int> left, KeyValuePair<object,int> right) { left.Value.CompareTo right.Value; }); 
    List<object> retList = new List<object>(); 
    foreach (var item in list) { 
    retList.Add(item.Key); 
    } 
    return retList; 
} 

LINQ Style Solution

public IEnumerable<string> GetPropertiesSorted(object obj) { 
    var type = obj.GetType(); 
    return type 
    .GetProperties() 
    .Select(x => new { 
     Value = x.GetValue(obj,null), 
     Attribute = (SortAttribute)Attribute.GetCustomAttribute(x, typeof(SortAttribute), false) }) 
    .OrderBy(x => x.Attribute.Order) 
    .Select(x => x.Value) 
    .Cast<string>(); 
} 
+2

Ваш ответ работает на C# 3 + и LINQ которым не доступны в рамках 2.0 – Argons

+0

@Argons, читайте прямо мимо 2,0 ограничение. Будет ли обновляться – JaredPar

+0

Если я хочу получить только атрибуты с атрибутом Sort? И разве код не проверяет, что нет двух свойств с одним и тем же порядком? – gdoron

Смежные вопросы