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));
można podać pełny kod fragment FillList –
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 –
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. –