2014-10-30 12 views
5

Mam listę object s. Jak mogę zamówić tę listę przy użyciu nazwy właściwości?Zamów listę według nazwy właściwości (wartość ciągu znaków)?

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

Czy mogę mieć rozszerzenie tego problemu?

+0

można podać pełny kod fragment FillList –

+1

problemem jest masz listę obiektów ** ** nie konkretna klasa tak jak można zapewnić, że cały obiekt na liście ma właściwość o nazwie "Kod" .. lepiej utworzyć listę określonego typu .. lub mając wiele typów użyć listy typów interfejsu –

+0

Nie mogę mieć określonego typu. FillList zwraca obiekt encji LINQ. s.t jak dc.Employer. Używam tej listy jako źródła danych niestandardowej siatki w MVC.NET. –

Odpowiedz

14

Jeśli nie musiał dostarczyć nazwę właściwości jako ciąg znaków, to całkiem proste używając dynamic:

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

Jeśli nazwa nieruchomość musi być ciągiem, to staje się coraz nieco skomplikowany, ale można to zrobić za pomocą odbicia (chociaż nie jest to bardzo efektywne):

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

Należy również pomyśleć o dodaniu obsługi błędów, np. jeśli właściwość nie istnieje.

Ponadto, jeśli wszystkie elementy na liście mają ten sam typ runtime, byłoby znacznie bardziej wydajne skompilowanie funkcji pobierającej za pomocą drzewek wyrażeń i ponowne użycie (zamiast bezpośredniego użycia odbicia).

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(); 
} 

i używać go jak:

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

Wielkie dzięki Eren. Działało. –

Powiązane problemy