Reputation: 3365
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.
Upvotes: 1
Views: 216
Reputation: 144206
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 });
Upvotes: 1
Reputation: 5850
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)
.
Upvotes: 0