1

I am trying to invoke a generic method via reflection using a subtype of the generic parameter type. Here's the situation :

public abstract class MyClass<T> where T : class
{
}

public static class Caller
{
    public static void Do<T>(MyClass<T> param1, string param2 = null) where T : class
    {

    }
}

public class ConcreteClass : MyClass<string>
{

}

However when I try to do :

ConcreteClass instance = Activator.CreateInstance(typeof(ConcreteClass));
MethodInfo methodInfo = typeof(Caller).GetMethod("Do");
methodInfo = methodInfo.MakeGenericMethod(typeof(ConcreteClass));
methodInfo.Invoke(null, new object[] { instance, Type.Missing });

I am getting an exception essentially saying :

Cannot convert type 'ConcreteClass' to type 'MyClass`[ConcreteClass]'

The exception message is very clear, however I don't seem to find how I can achieve what I am after.

Edit:

The compile time equivalent for what I am trying to achieve is :

Caller.Do(new ConcreteClass());

Which compiles fine.

2
  • Not sure if it's just from the example, but does MyClass<string> conform to your MyClass<T> where T : class requirements? Commented Oct 1, 2016 at 12:27
  • @Dan-Cook Many thanks for your interest in the question, yes it generally does (the string constraint is just for the example) Commented Oct 1, 2016 at 12:28

2 Answers 2

1

ConcreteClass extends MyClass<string> so you need to provide typeof(string) to MakeGenericMethod:

ConcreteClass instance = (ConcreteClass)Activator.CreateInstance(typeof(ConcreteClass));
MethodInfo methodInfo = typeof(Caller).GetMethod("Do");
methodInfo = methodInfo.MakeGenericMethod(typeof(string));
methodInfo.Invoke(null, new object[] { instance, Type.Missing });
Sign up to request clarification or add additional context in comments.

Comments

0

Your reflection-based code is attempting to the runtime equivalent of Caller.Do<ConcreteClass>(instance, Type.Missing).

This is invalid. The method Do<> requires matching types - for Do<ConcreteClass>, you need an instance that is or is a subclass of MyClass<ConcreteClass>.

ConcreteClass is a subclass of MyClass<string>. For this, you would need to call Do<string>(instance), or overall, Caller.Do<string>(instance, Type.Missing).

2 Comments

Thanks for your assistance but something is incorrect I'm afraid. Doing Caller.Do(new ConcreteClass()) is perfectly accepted by the compiler, therefore there should be a way to have the same approach using reflection.
That's because the compiler can correctly infer the correct types. With your reflection code, however, you're explicitly supplying an invalid combination of types.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.