反射:调用具有泛型列表的方法

本文关键字:列表 方法 泛型 调用 反射 | 更新日期: 2023-09-27 18:21:32

我有以下示例类:

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。只能对MethodBase.IsGenericMethodDefinition为true的方法调用MakeGenericMethod。

我在这里做错了什么?

反射:调用具有泛型列表的方法

我试过了,它很有效:

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

我注意到(不确定这是否只是示例中的错误)您的代码有问题。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);

这是有效的:

 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创建的泛型类的实例

如果你就是这样使用它的,为什么要让MyClass通用?这将明显更快:

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

然后打电话给

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