3

I want to implement generic pager and filter View Model for my project and I'm stuck on getting OrderBy method using reflection. Here is what I've tried, but keep getting null for methodInfo. It seems I'm passing the wrong Type[] arguments to the GetMethod() Method, but I can't get it right.

    protected virtual Expression<Func<T, IComparable>> GetOrderByExpression()
    {
        var type = typeof(T);
        var property = type.GetProperty("DataSetName");
        var parameter = Expression.Parameter(type, "x");
        var propertyAccess = Expression.MakeMemberAccess(parameter, property);
        var orderByExp = Expression.Lambda(propertyAccess, parameter);
        var methodInfo = typeof(Enumerable).GetMethod("OrderBy", new Type[] { orderByExp.Body.Type });
        var predicateBody = Expression.Call(propertyAccess, methodInfo, orderByExp);
        var expression = Expression.Lambda<Func<T, IComparable>>(predicateBody, parameter);

        return expression;
    }
2
  • As OrderBy is an extension method I'm not sure it will exist in that context. Commented Apr 1, 2015 at 9:17
  • 1
    This question, and answer appears to have the appropriate information to solve your issue. Commented Apr 1, 2015 at 9:20

1 Answer 1

4

Then Enumerable.OrderBy extension method is a static method so you have to use an overload to GetMethod where you can specify BindingFlags (BindingFlags.Static | BindingFlags.Public instead of the default BindingFlags.Instance | BindingFlags.Public).

You also have to specify two parameters to the method - syntactically it looks like there is only one parameter but because it is an extension method there is a second parameter which you have to specify.

This is the method you want to get via reflection:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
  this IEnumerable<TSource> source,
  Func<TSource, TKey> keySelector
)

You need the two parameter types:

var sourceType = typeof(IEnumerable<>).MakeGenericType(type);
var keySelectorType = orderByExp.Compile().GetType();

It seems that the only way to get a specific overload of a method with generic parameters you have to perform a search. Fortunately, there are only two overloads of Enumerable.OrderBy and the one you want is the one with two parameters:

var genericMethodInfo = typeof(Enumerable)
  .GetMethods(BindingFlags.Static | BindingFlags.Public)
  .First(mi => mi.Name == "OrderBy" && mi.GetParameters().Length == 2);
var methodInfo = genericMethodInfo.MakeGenericMethod(sourceType, keySelectorType);

This returns the desired MethodInfo, however you will have to modify the remaining two lines of code because this method is a static method and you have to specify a null instance in Expression.Call.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for that information. I was able to get the desired 'OrderBy' method.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.