Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order a list by a property name(string value)? [duplicate]

Tags:

c#

linq

I have a list of objects. How can I order this list using property name?

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

Can I have an extension for this problem?

like image 553
Siamak Ferdos Avatar asked Oct 30 '14 06:10

Siamak Ferdos


Video Answer


1 Answers

If you don't have to provide the property name as a string, it's pretty simple using dynamic:

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

If the property name has to be a string, then it gets more a bit complicated but can be done using reflection (although it is not very efficient):

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

You should also think about adding some error handling, e.g. if the property doesn't exist.

Also, if all the elements in the list have same runtime type, then it would be much more efficient to compile a getter function using expression trees and reusing it (instead of directly using reflection).

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

and use it like:

var codeGetter = CreateGetter(l[0].GetType(), "Code"); // using the 1st element as an example
l = l.OrderBy(o => codeGetter(o));
like image 161
Eren Ersönmez Avatar answered Oct 28 '22 00:10

Eren Ersönmez