Reputation: 5180
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?
Upvotes: 5
Views: 6052
Reputation: 17499
This works:
public static void TestMethod()
{
Type myClassType = typeof(MyClass<>);
Type[] typeArgs = { typeof(object) };
Type constructed = myClassType.MakeGenericType(typeArgs);
var myClassInstance = Activator.CreateInstance(constructed);
MethodInfo getAllMethod = constructed.GetMethod("GetAll", new Type[] { });
object magicValue = getAllMethod.Invoke(myClassInstance, null);
}
There are some errors in your code, as following:
GetMethod(...)
on the type object of your generic class (not on instance).getAllMethod.Invoke(...)
requires the instance of the generic class you have created using Activator
.Upvotes: 1
Reputation: 8613
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);
Upvotes: 1
Reputation: 4389
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);
Upvotes: 7
Reputation: 51319
If this is how you are using it, why are you bothering to make MyClass generic? This would be significantly faster:
public class MyClass
{
public IList GetAll()
{
return null; // of course, something more meaningfull happens here...
}
}
and then just call
var myObject = new MyClass();
var myList = myObject.GetAll();
Upvotes: 0