I have the following example-class:
public class MyClass<T>
{
public IList<T> GetAll()
{
return null; // of course, something more meaningfull happens here...
}
}
And I would like to invoke GetAll
with reflection:
Type myClassType = typeof(MyClass<>);
Type[] typeArgs = { typeof(object) };
Type constructed = myClassType.MakeGenericType(typeArgs);
var myClassInstance = Activator.CreateInstance(constructed);
MethodInfo getAllMethod = myClassType.GetMethod("GetAll", new Type[] {});
object magicValue = getAllMethod.Invoke(myClassInstance, null);
This results in (on last line of above code):
Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.
Okay, second try:
MethodInfo getAllMethod = myClassType.GetMethod("GetAll", new Type[] {});
getAllMethod = getAllMethod.MakeGenericMethod(typeof(object));
object magicValue = getAllMethod.Invoke(myClassInstance, null);
This results in (on second last line of above code):
System.Collections.Generic.IList`1[T] GetAll() is not a GenericMethodDefinition. MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true.
What am I doing wrong here?
The first step to dynamically invoking a generic method with reflection is to use reflection to get access to the MethodInfo of the generic method. To do that simply do this: var methodInfo = typeof(ClassWithGenericMethod). GetMethod("MethodName");
Then, we construct a generic version of it by calling the MakeGenericMethod() with the target type. To invoke this generic method, we need two things: an instance of the owner class of the method and the necessary arguments for the parameters of the original method in form of an object array.
Because the Common Language Runtime (CLR) has access to generic type information at run time, you can use reflection to obtain information about generic types in the same way as for non-generic types.
I've tried this and it works:
// Create generic type
Type myClassType = typeof(MyClass<>);
Type[] typeArgs = { typeof(object) };
Type constructed = myClassType.MakeGenericType(typeArgs);
// Create instance of generic type
var myClassInstance = Activator.CreateInstance(constructed);
// Find GetAll() method and invoke
MethodInfo getAllMethod = constructed.GetMethod("GetAll");
object result = getAllMethod.Invoke(myClassInstance, null);
I've noticed (not sure if it's just an error in your sample) that there is a problem with your code. myClassInstance
will be of type object
and so you cannot call GetMethod(...)
on it. I think you may mean to call that on the type instead. Secondly, you are passing baseRepo
as the object to invoke the method on - surely you want to invoke the method on the instantiation of the type - in this case, the variable myClassInstance
?
If you modify your code this way, you should have something like the below code (which, when testing, works):
Type classType = typeof(MyClass<>);
Type[] typeArgs = { typeof(object) };
Type fullClassType = classType.MakeGenericType(typeArgs);
var classInstance = Activator.CreateInstance(fullClassType);
MethodInfo method = fullClassType.GetMethod("GetAll", new Type[0]);
object result = method.Invoke(classInstance, null);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With