Skip to content

Instantly share code, notes, and snippets.

@shanecelis
Created February 21, 2017 21:58
Show Gist options
  • Save shanecelis/a0fca4fdf489e808c98057b49ec003c1 to your computer and use it in GitHub Desktop.
Save shanecelis/a0fca4fdf489e808c98057b49ec003c1 to your computer and use it in GitHub Desktop.
Search for a method based on generic arguments in addition to name and parameters.
/**
Search for a method based on generic arguments in addition to name and
parameters. Most useful for disambiguating methods with the same name.
If the elements of genericArgs are not null, it will return the specialized
generic method. Otherwise it will return the generic method definition.
Finally, if genericArgs has no elements, it will return a non-generic
method. If no method is found, it will return null.
e.g. Suppose I had the following methods in a class Minibuffer:
IPromise<string> Read(Prompt p) { ... }
IPromise<T> Read<T>(Prompt p) { ... }
And I wanted to get the generic one:
Minibuffer.GetMethodGeneric("Read", new [] {typeof(int)}, new [] {typeof(Prompt)}) ->
IPromise`1 Read[Int64](seawisphunter.minibuffer.Prompt)
Minibuffer.GetMethodGeneric("Read", new Type[] {null}, new [] {typeof(Prompt)}) ->
IPromise`1 Read[T](seawisphunter.minibuffer.Prompt)
Or I could get the non-generic one:
Minibuffer.GetMethodGeneric("Read", new Type[] {}, new [] {typeof(Prompt)}) ->
IPromise`1 Read(seawisphunter.minibuffer.Prompt)
*/
// http://stackoverflow.com/questions/5218395/reflection-how-to-get-a-generic-method
public static MethodInfo GetMethodGeneric(this Type t,
string name,
Type[] genericArgs,
Type[] parameterTypes) {
var myMethod
= t
.GetMethods()
// I can count the number of times I've had to actually XOR on one hand.
.Where(m => (genericArgs.Length == 0 ^ m.IsGenericMethod)
&& m.Name == name)
.Where(m =>
{
var paramTypes = m.GetParameters();
var genParams = m.GetGenericArguments();
return genParams.Length == genericArgs.Length
&& Enumerable.SequenceEqual(paramTypes.Select(p => p.ParameterType),
parameterTypes);
})
.SingleOrDefault();
if (myMethod != null
&& myMethod.ContainsGenericParameters
&& genericArgs.All(p => p != null)) {
return myMethod.MakeGenericMethod(genericArgs);
}
return myMethod;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment