You can elegantly select a certain general method overload at compile time without passing a single line to temporary requests, like the other answers here.
Static methods
Suppose you have several static methods with the same name as:
public static void DoSomething<TModel>(TModel model) public static void DoSomething<TViewModel, TModel>(TViewModel viewModel, TModel model)
If you create an Action or Func that matches the total score and the number of overload options you are looking for, you can select it at compile time with relatively little acrobatics.
Example: select the first method - it returns void, so use Action, it takes one common one. We use the object to not yet indicate the type:
var method = new Action<object>(MyClass.DoSomething<object>);
Example: select the second method - it returns void, therefore Action is of 2 generic types, therefore use the type object twice, once for each of two common parameters:
var method = new Action<object, object>(MyClass.DoSomething<object, object>);
You just got the method you need, without crazy plumbing, and without searching in time or using risky strings.
Methodinfo
Usually in Reflection, you need a MethodInfo object, which you can also get in a compiled way. This is when you pass the actual generic types that you want to use in your method. Assuming you need the second method above:
var methodInfo = method.Method.MakeGenericMethod(type1, type2);
Here is your general method without looking for reflections or calls to GetMethod () or fake strings.
Static Extension Methods
The specific example you are quoting from Queryable.Where the overload makes you look a bit fancy to define Func, but usually follows the same pattern. Signature for the most commonly used Where () extension method :
public static IQueryable<TModel> Where<TModel>(this IQueryable<TModel>, Expression<Func<TModel, bool>>)
Obviously, it will be a little more complicated - here it is:
var method = new Func<IQueryable<object>, Expression<Func<object, bool>>, IQueryable<object>>(Queryable.Where<object>); var methodInfo = method.Method.MakeGenericMethod(modelType);
Instance Methods
Enabling Valerie comment - in order to get the instance method, you need to do something very similar. Suppose you have this instance method in your class:
public void MyMethod<T1>(T1 thing)
First, select the method in the same way as for statics:
var method = new Action<object>(MyMethod<object>);
Then call GetGenericMethodDefinition() to go to the generic MethodInfo, and finally pass your type with MakeGenericMethod() :
var methodInfo = method.Method.GetGenericMethodDefinition().MakeGenericMethod(type1);
MethodInfo decoupling and parameter types
This was not asked in the question, but as soon as you do this, you can choose a method in one place and decide which types to pass it to another. You can separate these 2 steps.
If you are not sure about the generic type parameters that you are going to pass, you can always acquire a MethodInfo object without them.
Static
var methodInfo = method.Method;
Instance:
var methodInfo = method.Method.GetGenericMethodDefinition();
And pass this to another method that knows the types it wants to create, and will call the method with - for example:
processCollection(methodInfo, type2); ... protected void processCollection(MethodInfo method, Type type2) { var type1 = typeof(MyDataClass); object output = method.MakeGenericMethod(type1, type2).Invoke(null, new object[] { collection }); }
One thing that helps a lot is to choose a specific class instance method from within the class and then expose it to external callers who need it with different types later.
Editing: Cleared explanations, included Valerie instance method example.