2014-10-30 3 views
5

У меня есть список object s. Как я могу заказать этот список, используя имя свойства?Заказать список по имени свойства (строковое значение)?

string orderbyField = "Code"; 
List<object> l = FillList(); 
l = l.OrderBy(o => orderbyField); 

Могу ли я получить расширение для этой проблемы?

+0

Можете ли вы представить свой полный фрагмент кода FillList –

+1

беспокойство вызывает у вас есть список ** объекта ** не конкретный класс, так как вы можете гарантировать, что весь объект внутри списка имеет свойство с именем «Код» .. лучше создать список определенного типа .. или иметь список типов интерфейса типа типа –

+0

У меня не может быть определенного типа. FillList возвращает объект объекта LINQ. s.t как dc.Employer. Я использую этот список как источник данных настраиваемой сетки в MVC.NET. –

ответ

14

Если вы не должны указать имя свойства в виде строки, это довольно просто с помощью dynamic:

List<object> l = FillList(); 
l = l.OrderBy(o => ((dynamic)o).Id); 

Если имя свойства должно быть строкой, то он становится более немного сложнее, но может быть сделано с использованием отражения (хотя это не очень эффективно):

l = l.OrderBy(o => o.GetType() 
        .GetProperty("Code") 
        .GetValue(o, null)); 

Вы также должны подумать о добавлении некоторой обработки ошибок, например если свойство не существует.

Кроме того, если все элементы в списке имеют одинаковые тип времени выполнения, то было бы гораздо более эффективно скомпилировать функцию-геттер с использованием деревьев выражений и повторного использования (вместо прямого использования отражения).

public static Func<object, object> CreateGetter(Type runtimeType, string propertyName) 
{ 
    var propertyInfo = runtimeType.GetProperty(propertyName); 

    // create a parameter (object obj) 
    var obj = Expression.Parameter(typeof(object), "obj"); 

    // cast obj to runtimeType 
    var objT = Expression.TypeAs(obj, runtimeType); 

    // property accessor 
    var property = Expression.Property(objT, propertyInfo); 

    var convert = Expression.TypeAs(property, typeof(object)); 
    return (Func<object, object>)Expression.Lambda(convert, obj).Compile(); 
} 

и использовать его как:

var codeGetter = CreateGetter(l[0].GetType(), "Code"); // using the 1st element as an example 
l = l.OrderBy(o => codeGetter(o)); 
+0

Спасибо большое Эрен. –

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