Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a generic method without using GetMethods

I want to get the method System.Linq.Queryable.OrderyBy<T, TKey>(the IQueryable<T> source, Expression<Func<T,TKey>> keySelector) method, but I keep coming up with nulls.

var type = typeof(T); var propertyInfo = type.GetProperty(group.PropertyName); var propertyType = propertyInfo.PropertyType;  var sorterType = typeof(Func<,>).MakeGenericType(type, propertyType); var expressionType = typeof(Expression<>).MakeGenericType(sorterType);  var queryType = typeof(IQueryable<T>);  var orderBy = typeof(System.Linq.Queryable).GetMethod("OrderBy", new[] { queryType, expressionType }); /// is always null. 

Does anyone have any insight? I would prefer to not loop through the GetMethods result.

like image 518
David Avatar asked Nov 06 '08 17:11

David


People also ask

Can you have a generic method in a non generic class?

Yes, you can define a generic method in a non-generic class in Java.

What is a generic method and when should it be used C#?

Generics allow you to define the specification of the data type of programming elements in a class or a method, until it is actually used in the program. In other words, generics allow you to write a class or method that can work with any data type.

How do you create a generic method in C#?

You can create an instance of generic classes by specifying an actual type in angle brackets. The following creates an instance of the generic class DataStore . DataStore<string> store = new DataStore<string>(); Above, we specified the string type in the angle brackets while creating an instance.


Video Answer


1 Answers

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).

like image 189
Neil Avatar answered Oct 08 '22 23:10

Neil