linq Order By for a List(Of myObjects)
VB
Module OrderByExtensions
<System.Runtime.CompilerServices.Extension()> _
Public Function OrderByPropertyName(Of T)(ByVal e As IEnumerable(Of T), ByVal propertyName As String) As IOrderedEnumerable(Of T)
Dim itemType = GetType(T)
Dim prop = itemType.GetProperty(propertyName)
If prop Is Nothing Then Throw New ArgumentException("Object does not have the specified property")
Dim propType = prop.PropertyType
Dim funcType = GetType(Func(Of ,)).MakeGenericType(itemType, propType)
Dim parameter = Expression.Parameter(itemType, "item")
Dim exp = Expression.Lambda(funcType, Expression.MakeMemberAccess(parameter, prop), parameter)
Dim params = New Object() {e, exp.Compile()}
Return DirectCast(GetType(OrderByExtensions).GetMethod("InvokeOrderBy", Reflection.BindingFlags.Static Or Reflection.BindingFlags.NonPublic).MakeGenericMethod(itemType, propType).Invoke(Nothing, params), IOrderedEnumerable(Of T))
End Function
Private Function InvokeOrderBy(Of T, U)(ByVal e As IEnumerable(Of T), ByVal f As Func(Of T, U)) As IOrderedEnumerable(Of T)
Return Enumerable.OrderBy(e, f)
End Function
End Module
C#
public static class OrderByExtensions
{
public static IOrderedEnumerable<T> OrderByPropertyName<T>(this IEnumerable<T> e, string name)
{
var itemType = typeof(T);
var prop = itemType.GetProperty(name);
if (prop == null) throw new ArgumentException("Object does not have the specified property");
var propType = prop.PropertyType;
var funcType = typeof(Func<,>).MakeGenericType(itemType, propType);
var parameter = Expression.Parameter(itemType, "item");
var memberAccess = Expression.MakeMemberAccess(parameter, prop);
var expression = Expression.Lambda(funcType, memberAccess, parameter);
var x = typeof(OrderByExtensions).GetMethod("InvokeOrderBy", BindingFlags.Static | BindingFlags.NonPublic);
return (IOrderedEnumerable<T>)x.MakeGenericMethod(itemType, propType).Invoke(null, new object[] { e, expression.Compile() });
}
static IOrderedEnumerable<T> InvokeOrderBy<T, U>(IEnumerable<T> e, Func<T, U> f)
{
return e.OrderBy(f);
}
}
Pass the sort column as an Function.
So it would be
public SomeList Foo(Function<Foo, bool> sortFunction, int skip, int PageSize)
{
return returnReports.OrderBy(sortFunction).Skip(skip).Take(PageSize).ToList();
}
Call it like this
SomeList(f => f.Bar, 5, 10);
if you're working with a database as a source of data then you can use Dynamic LINQ project that allows you to specify parameters to the Where clause as a string.
If you're working with "Linq to objects" than you'll need to create the lambda function that is passed as an argument dynamically. You can do this by using the "Expression.Xyz" methods to build the expression tree and then using the "Compile" method that turns the expression tree into a callable delegate (of type Func<>) that you can use as an argument to Where. An example how to construct the expression tree can be found in another SO thread here.