Как отсортировать общий список на основе пользовательского атрибута? - PullRequest
5 голосов
/ 09 февраля 2010

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

Используя отражение, я прочитал все свойства, сгруппировал значения и поместил их в общий список свойств. Это работает, и я могу взять значения. Но план был СОРТИРОВАТЬ список, основанный на настраиваемом атрибуте, помещенном в каждое свойство, и, наконец, считывать уже упорядоченные значения свойств в строку.

1 Ответ

11 голосов
/ 09 февраля 2010

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

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>();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...