Solved (by hacking LINQ)!
I saw your question while researching the same problem. After finding no good solution, I had the idea to look at the LINQ expression tree. Here's what I came up with:
public static MethodInfo GetOrderByMethod<TElement, TSortKey>()
{
Func<TElement, TSortKey> fakeKeySelector = element => default(TSortKey);
Expression<Func<IEnumerable<TElement>, IOrderedEnumerable<TElement>>> lamda
= list => list.OrderBy(fakeKeySelector);
return (lamda.Body as MethodCallExpression).Method;
}
static void Main(string[] args)
{
List<int> ints = new List<int>() { 9, 10, 3 };
MethodInfo mi = GetOrderByMethod<int, string>();
Func<int,string> keySelector = i => i.ToString();
IEnumerable<int> sortedList = mi.Invoke(null, new object[] { ints,
keySelector }
) as IEnumerable<int>;
foreach (int i in sortedList)
{
Console.WriteLine(i);
}
}
output: 10 3 9
EDIT: Here is how to get the method if you don't know the type at compile-time:
public static MethodInfo GetOrderByMethod(Type elementType, Type sortKeyType)
{
MethodInfo mi = typeof(Program).GetMethod("GetOrderByMethod", Type.EmptyTypes);
var getOrderByMethod = mi.MakeGenericMethod(new Type[] { elementType,
sortKeyType });
return getOrderByMethod.Invoke(null, new object[] { }) as MethodInfo;
}
Be sure to replace typeof(Program) with typeof(WhateverClassYouDeclareTheseMethodsIn).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…