反射:作为结果使用通用列表调用方法

时间:2012-01-27 15:37:18

标签: c# generics reflection

我有以下示例类:

public class MyClass<T>
{
    public IList<T> GetAll()
    {
        return null; // of course, something more meaningfull happens here...
    }
}

我想用反思调用GetAll

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

这导致(在上面代码的最后一行):

  

无法对ContainsGenericParameters为true的类型或方法执行后期绑定操作。

好的,第二次尝试:

MethodInfo getAllMethod = myClassType.GetMethod("GetAll", new Type[] {});
getAllMethod = getAllMethod.MakeGenericMethod(typeof(object));
object magicValue = getAllMethod.Invoke(myClassInstance, null);

这导致(在上面代码的倒数第二行):

  

System.Collections.Generic.IList`1 [T] GetAll()不是GenericMethodDefinition。 MakeGenericMethod只能在MethodBase.IsGenericMethodDefinition为true的方法上调用。

我在这里做错了什么?

4 个答案:

答案 0 :(得分:6)

我试过这个并且它有效:

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

答案 1 :(得分:1)

我注意到(不确定您的示例中是否只是一个错误)您的代码存在问题。 myClassInstance的类型为object,因此您无法在其上调用GetMethod(...)。我想你可能打算在类型上调用它。其次,您正在传递baseRepo作为调用方法的对象 - 当然您要在类型的实例化上调用方法 - 在这种情况下,变量myClassInstance

如果你以这种方式修改你的代码,你应该有类似下面的代码(在测试时,它可以工作):

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

答案 2 :(得分:1)

这有效:

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

您的代码中存在一些错误,如下所示:

  • 您需要在泛型类的类型对象上调用GetMethod(...)(而不是在实例上)。
  • getAllMethod.Invoke(...)需要您使用Activator创建的泛型类的实例。

答案 3 :(得分:0)

如果您正在使用它,为什么还要麻烦MyClass通用?这会明显加快:

public class MyClass
{
    public IList GetAll()
    {
        return null; // of course, something more meaningfull happens here...
    }
}

然后只需致电

var myObject = new MyClass();
var myList = myObject.GetAll();