Krzysztof Kozmic
Krzysztof Kozmic

Reputation: 27384

Is there a good way of getting MethodInfo of open generic method?

Consider type like this one

public interface IHaveGenericMethod
{
   T1 Method<T1>(T1 parm);
   T2 Method<T1,T2>(T1 parm);
   int Method2(int parm);
}

How do I get a methodInfo for its methods? for a regular non-generic method, like method2, I can go with

typeof(IHaveGenericMethod).GetMethod("methodName",new Type[]{typeof(itsParameters)});

for a generic method though, I can't, since it's parameters are not types per-se. So, how do I do that? I know that I can call

typeof(IHaveGenericMethod).GetMethods()

to get all methods of that type, and then iterate over that collection and do some matching, but it's ugly. Is there a better way?

Upvotes: 3

Views: 1129

Answers (3)

fso
fso

Reputation: 154

I personaly do the following:

public static MethodInfo ExtractMethodInfo<TDeclaringType, TMethod>(Expression<Func<TDeclaringType, TMethod>> methodAccessExpression) {
    return (MethodInfo)((ConstantExpression)((MethodCallExpression)((UnaryExpression)methodAccessExpression.Body).Operand).Object).Value;
}

var genericQueryMethodInfo = ExpressionHelper.ExtractMethodInfo<DbContext, Func<IQueryable<object>>>(context => context.Query<object>).GetGenericMethodDefinition();

This way, you are sure to find the right one, and I think it's better than iterating over all methodInfos.

Upvotes: 0

Jay Bazuzi
Jay Bazuzi

Reputation: 46546

Be sure to check out the MSDN page "Reflection and Generic Types".

since it's parameters are not types per-se

Actually, I think it's because you want to query type parameters, but the type list you can provide to GetMethod() is not for type parameters.

Also, remember that all you need to select a "method group" of generic methods is to know the number of generic type parameters. So you can just count them.

then iterate

Don't iterate, query:

       var mi = from mi in typeof(IHaveGenericMethod).GetMethods()
                where mi.Name == "Method"
                where mi.IsGenericMethodDefinition
                where mi.GetGenericArguments().Length == 2
                select mi;

Upvotes: 2

Marc Gravell
Marc Gravell

Reputation: 1064244

Well, they are types - of sorts:

    foreach (var method in typeof(IHaveGenericMethod).GetMethods())
    {
        Console.WriteLine(method.Name);
        if (method.IsGenericMethodDefinition)
        {
            foreach (Type type in method.GetGenericArguments())
            {
                Console.WriteLine("> " + type.Name);
            }
        }
    }

So you can check by the number of args, and check the signature. But nothing cleaner.

Upvotes: 1

Related Questions