5

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?

7
  • Where did baseRepo come from in the last line? Shouldn't it be myClassInstance? Commented Jan 27, 2012 at 15:51
  • Your sample code must have a bug in this line: MethodInfo getAllMethod = myClassInstance.GetMethod("GetAll", new Type[] {}); Commented Jan 27, 2012 at 15:52
  • Yes, OP probably used myClassType there instead of constructed. After I corrected that, it worked for me. Commented Jan 27, 2012 at 15:53
  • Example here: stackoverflow.com/questions/232535/… Commented Jan 27, 2012 at 15:53
  • Sorry for the code-errors, happend from simplifying it... fixed that. Commented Jan 27, 2012 at 15:58

4 Answers 4

7

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); 
Sign up to request clarification or add additional context in comments.

1 Comment

Thx - it was a silly mistake... constructed.GetMethod("GetAll"); is correct of course, or in my case myClassInstance.GetMethod("GetAll", new Type[] {});
1

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);

Comments

1

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:

  • You need to call 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.

Comments

0

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();

2 Comments

My guess would be that making it of Type object was just for the example, to make it as easy to understand as possible
Exactly: It is a simplified example. There is good reason why it is like that and why I have to use reflection on an other place.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.