Dynamically merging the <T> orderby list
I am writing a method to expand a sort list. My input is a list and a string with the property name and sort direction. This line can have several properties: "ASC Name, DESC Date", etc.
I already parsed the string and used reflection to get the property itself from the string, but now I'm stuck with how to dynamically bind orderby methods.
something like: _list.orderBy(x=>x.prop1).thenBy(x=>x.prop2) , etc.
Is there any way to build this dynamically?
Use reflection to get string names from PropertyInfo from property names. Then you can build an expression tree using PropertyInfo to dynamically build all orderbys. When you have an expression tree, compile it for the delegate (say Func, IEnumerable>) Go to your _list parameter to that delegate and it will give you an ordered result as another enumerable.
To get reflection information for a generic method in Enumerable, take a look at the answer to this post: Get a generic method without using GetMethods methods
public static class Helper { public static IEnumerable<T> BuildOrderBys<T>( this IEnumerable<T> source, params SortDescription[] properties) { if (properties == null || properties.Length == 0) return source; var typeOfT = typeof (T); Type t = typeOfT; IOrderedEnumerable<T> result = null; var thenBy = false; foreach (var item in properties .Select(prop => new {PropertyInfo = t.GetProperty(prop.PropertyName), prop.Direction})) { var oExpr = Expression.Parameter(typeOfT, "o"); var propertyInfo = item.PropertyInfo; var propertyType = propertyInfo.PropertyType; var isAscending = item.Direction == ListSortDirection.Ascending; if (thenBy) { var prevExpr = Expression.Parameter(typeof (IOrderedEnumerable<T>), "prevExpr"); var expr1 = Expression.Lambda<Func<IOrderedEnumerable<T>, IOrderedEnumerable<T>>>( Expression.Call( (isAscending ? thenByMethod : thenByDescendingMethod).MakeGenericMethod(typeOfT, propertyType), prevExpr, Expression.Lambda( typeof (Func<,>).MakeGenericType(typeOfT, propertyType), Expression.MakeMemberAccess(oExpr, propertyInfo), oExpr) ), prevExpr) .Compile(); result = expr1(result); } else { var prevExpr = Expression.Parameter(typeof (IEnumerable<T>), "prevExpr"); var expr1 = Expression.Lambda<Func<IEnumerable<T>, IOrderedEnumerable<T>>>( Expression.Call( (isAscending ? orderByMethod : orderByDescendingMethod).MakeGenericMethod(typeOfT, propertyType), prevExpr, Expression.Lambda( typeof (Func<,>).MakeGenericType(typeOfT, propertyType), Expression.MakeMemberAccess(oExpr, propertyInfo), oExpr) ), prevExpr) .Compile(); result = expr1(source); thenBy = true; } } return result; } private static MethodInfo orderByMethod = MethodOf(() => Enumerable.OrderBy(default(IEnumerable<object>), default(Func<object, object>))) .GetGenericMethodDefinition(); private static MethodInfo orderByDescendingMethod = MethodOf(() => Enumerable.OrderByDescending(default(IEnumerable<object>), default(Func<object, object>))) .GetGenericMethodDefinition(); private static MethodInfo thenByMethod = MethodOf(() => Enumerable.ThenBy(default(IOrderedEnumerable<object>), default(Func<object, object>))) .GetGenericMethodDefinition(); private static MethodInfo thenByDescendingMethod = MethodOf(() => Enumerable.ThenByDescending(default(IOrderedEnumerable<object>), default(Func<object, object>))) .GetGenericMethodDefinition(); public static MethodInfo MethodOf<T>(Expression<Func<T>> method) { MethodCallExpression mce = (MethodCallExpression) method.Body; MethodInfo mi = mce.Method; return mi; } } public static class Sample { private static void Main() { var data = new List<Customer> { new Customer {ID = 3, Name = "a"}, new Customer {ID = 3, Name = "c"}, new Customer {ID = 4}, new Customer {ID = 3, Name = "b"}, new Customer {ID = 2} }; var result = data.BuildOrderBys( new SortDescription("ID", ListSortDirection.Ascending), new SortDescription("Name", ListSortDirection.Ascending) ).Dump(); } } public class Customer { public int ID { get; set; } public string Name { get; set; } } Sample result as shown in LinqPad

You can use something like this:
var query = _list.OrderBy(x=>x.prop1); if (shouldOrderByProp2Too) query = query.ThenBy(x=>x.prop2); if (shouldOrderByProp3Too) query = query.ThenBy(x=>x.prop3); // ... // then use query the way you had your code For your comment: In this case, I would implement the IComparable implementation on the objects in your list, and then just sort it / or use Compareres, which dynamically check for it, the only thing I can think of is to do with reflection and dynamic invocation. .. not the thing you want to do if it is not necessary;)